# Enable warning for deprecated language features.
art_clang_cflags += -Wdeprecated
+# Enable warning for unreachable break & return, and missing NO_RETURN annotations.
+art_clang_cflags += -Wunreachable-code-break -Wunreachable-code-return -Wmissing-noreturn
+
# GCC-only warnings.
art_gcc_cflags := -Wunused-but-set-parameter
default:
LOG(FATAL) << "Unexpected opcode: " << opcode;
UNREACHABLE();
- break;
}
if (mir->ssa_rep->num_defs != 0) {
DCHECK_EQ(shift, 0);
// Binary, but rm is encoded twice.
return NewLIR2(kA64Rev2rr | wide, r_dest_src1.GetReg(), r_src2.GetReg());
- break;
case kOpRevsh:
// Binary, but rm is encoded twice.
NewLIR2(kA64Rev162rr | wide, r_dest_src1.GetReg(), r_src2.GetReg());
// "sxth r1, r2" is "sbfm r1, r2, #0, #15"
return NewLIR4(kA64Sbfm4rrdd | wide, r_dest_src1.GetReg(), r_dest_src1.GetReg(), 0, 15);
- break;
case kOp2Byte:
DCHECK_EQ(shift, ENCODE_NO_SHIFT);
// "sbfx r1, r2, #imm1, #imm2" is "sbfm r1, r2, #imm1, #(imm1 + imm2 - 1)".
// Note: intentional fallthrough
case kOpSub:
return OpRegRegRegExtend(op, r_dest_src1, r_dest_src1, r_src2, ext, amount);
- break;
default:
LOG(FATAL) << "Bad Opcode: " << opcode;
- break;
+ UNREACHABLE();
}
DCHECK(!IsPseudoLirOp(opcode));
break;
case kOpBx:
return NewLIR2(kMipsJalr, rZERO, r_dest_src.GetReg());
- break;
default:
LOG(FATAL) << "Bad case in OpReg";
+ UNREACHABLE();
}
return NewLIR2(opcode, cu_->target64 ? rRAd : rRA, r_dest_src.GetReg());
}
return OpRegRegImm(op, r_dest_src1, r_dest_src1, value);
} else {
LOG(FATAL) << "Bad case in OpRegImm";
+ UNREACHABLE();
}
- UNREACHABLE();
}
LIR* MipsMir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2) {
switch (instruction_set) {
case kX86:
return std::unique_ptr<RelativePatcher>(new X86RelativePatcher());
- break;
case kX86_64:
return std::unique_ptr<RelativePatcher>(new X86_64RelativePatcher());
- break;
case kArm:
// Fall through: we generate Thumb2 code for "arm".
case kThumb2:
return std::unique_ptr<RelativePatcher>(new Thumb2RelativePatcher(provider));
- break;
case kArm64:
return std::unique_ptr<RelativePatcher>(
new Arm64RelativePatcher(provider, features->AsArm64InstructionSetFeatures()));
- break;
default:
return std::unique_ptr<RelativePatcher>(new RelativePatcherNone);
- break;
}
}
*underflow = true;
return Min();
}
- return ValueBound(instruction_, new_constant);
}
private:
}
LOG(FATAL) << "Could not find a register in baseline register allocator";
UNREACHABLE();
- return -1;
}
size_t CodeGenerator::FindTwoFreeConsecutiveAlignedEntries(bool* array, size_t length) {
}
LOG(FATAL) << "Could not find a register in baseline register allocator";
UNREACHABLE();
- return -1;
}
void CodeGenerator::InitializeCodeGeneration(size_t number_of_spill_slots,
case Primitive::kPrimLong:
case Primitive::kPrimDouble:
return Location::DoubleStackSlot(GetStackSlot(load->GetLocal()));
- break;
case Primitive::kPrimInt:
case Primitive::kPrimNot:
case Primitive::kPrimShort:
case Primitive::kPrimVoid:
LOG(FATAL) << "Unexpected type " << load->GetType();
+ UNREACHABLE();
}
LOG(FATAL) << "Unreachable";
- return Location();
+ UNREACHABLE();
}
Location InvokeDexCallingConventionVisitor::GetNextLocation(Primitive::Type type) {
return Location();
}
UNREACHABLE();
- return Location();
}
void CodeGeneratorARM::Move32(Location destination, Location source) {
case Primitive::kPrimLong:
case Primitive::kPrimDouble:
return Location::DoubleStackSlot(GetStackSlot(load->GetLocal()));
- break;
case Primitive::kPrimInt:
case Primitive::kPrimNot:
case Primitive::kPrimShort:
case Primitive::kPrimVoid:
LOG(FATAL) << "Unexpected type " << load->GetType();
+ UNREACHABLE();
}
LOG(FATAL) << "Unreachable";
- return Location();
+ UNREACHABLE();
}
Location InvokeDexCallingConventionVisitor::GetNextLocation(Primitive::Type type) {
case Primitive::kPrimLong:
case Primitive::kPrimDouble:
return Location::DoubleStackSlot(GetStackSlot(load->GetLocal()));
- break;
case Primitive::kPrimInt:
case Primitive::kPrimNot:
case Primitive::kPrimShort:
case Primitive::kPrimVoid:
LOG(FATAL) << "Unexpected type " << load->GetType();
+ UNREACHABLE();
}
LOG(FATAL) << "Unreachable";
- return Location();
+ UNREACHABLE();
}
void CodeGeneratorX86_64::Move(Location destination, Location source) {
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
- break;
case kIntrinsicReverseBytes:
switch (GetType(method.d.data, true)) {
case Primitive::kPrimShort:
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
- break;
// Abs.
case kIntrinsicAbsDouble:
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
- break;
// Memory.poke.
case kIntrinsicPoke:
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
- break;
// String.
case kIntrinsicCharAt:
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
- break;
case kIntrinsicUnsafeGet: {
const bool is_volatile = (method.d.data & kIntrinsicFlagIsVolatile);
switch (GetType(method.d.data, false)) {
LOG(FATAL) << "Unknown/unsupported op size " << method.d.data;
UNREACHABLE();
}
- break;
}
case kIntrinsicUnsafePut: {
enum Sync { kNoSync, kVolatile, kOrdered };
} else {
return immed_;
}
- break;
case kRegister:
if (is_shift_) {
uint32_t shift_type;
// Simple register
return static_cast<uint32_t>(rm_);
}
- break;
default:
// Can't get here.
LOG(FATAL) << "Invalid shifter operand for ARM";
// Simple register
return static_cast<uint32_t>(rm_);
}
- break;
default:
// Can't get here.
LOG(FATAL) << "Invalid shifter operand for thumb";
- return 0;
+ UNREACHABLE();
}
- return 0;
}
uint32_t Address::encodingArm() const {
break;
case TEQ:
return true;
- break;
case ADD:
case SUB:
break;
// TODO: make vixl clean wrt -Wshadow.
#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#include "vixl/a64/macro-assembler-a64.h"
#include "vixl/a64/disasm-a64.h"
#pragma GCC diagnostic pop
}
continue; // No ", ".
}
- break;
case 'I': // Upper 16-bit immediate.
args << reinterpret_cast<void*>((instruction & 0xffff) << 16);
break;
}
continue; // No ", ".
}
- break;
case 'I': // Upper 16-bit immediate.
args << reinterpret_cast<void*>((instruction & 0xffff) << 16);
break;
// A macro to disallow new and delete operators for a class. It goes in the private: declarations.
#define DISALLOW_ALLOCATION() \
public: \
- ALWAYS_INLINE void operator delete(void*, size_t) { UNREACHABLE(); } \
+ NO_RETURN ALWAYS_INLINE void operator delete(void*, size_t) { UNREACHABLE(); } \
private: \
void* operator new(size_t) = delete
namespace art {
-extern "C" void artDeoptimize(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+extern "C" NO_RETURN void artDeoptimize(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
self->SetException(Thread::GetDeoptimizationException());
self->QuickDeliverException();
namespace art {
// Deliver an exception that's pending on thread helping set up a callee save frame on the way.
-extern "C" void artDeliverPendingExceptionFromCode(Thread* self)
+extern "C" NO_RETURN void artDeliverPendingExceptionFromCode(Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
self->QuickDeliverException();
}
// Called by generated call to throw an exception.
-extern "C" void artDeliverExceptionFromCode(mirror::Throwable* exception, Thread* self)
+extern "C" NO_RETURN void artDeliverExceptionFromCode(mirror::Throwable* exception, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
/*
* exception may be NULL, in which case this routine should
}
// Called by generated call to throw a NPE exception.
-extern "C" void artThrowNullPointerExceptionFromCode(Thread* self)
+extern "C" NO_RETURN void artThrowNullPointerExceptionFromCode(Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
self->NoteSignalBeingHandled();
}
// Called by generated call to throw an arithmetic divide by zero exception.
-extern "C" void artThrowDivZeroFromCode(Thread* self)
+extern "C" NO_RETURN void artThrowDivZeroFromCode(Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
ThrowArithmeticExceptionDivideByZero();
}
// Called by generated call to throw an array index out of bounds exception.
-extern "C" void artThrowArrayBoundsFromCode(int index, int length, Thread* self)
+extern "C" NO_RETURN void artThrowArrayBoundsFromCode(int index, int length, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
ThrowArrayIndexOutOfBoundsException(index, length);
self->QuickDeliverException();
}
-extern "C" void artThrowStackOverflowFromCode(Thread* self)
+extern "C" NO_RETURN void artThrowStackOverflowFromCode(Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
self->NoteSignalBeingHandled();
self->QuickDeliverException();
}
-extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self)
+extern "C" NO_RETURN void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
ThrowNoSuchMethodError(method_idx);
self->QuickDeliverException();
}
-extern "C" void artThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type,
- Thread* self)
+extern "C" NO_RETURN void artThrowClassCastException(mirror::Class* dest_type,
+ mirror::Class* src_type,
+ Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
DCHECK(!dest_type->IsAssignableFrom(src_type));
self->QuickDeliverException();
}
-extern "C" void artThrowArrayStoreException(mirror::Object* array, mirror::Object* value,
- Thread* self)
+extern "C" NO_RETURN void artThrowArrayStoreException(mirror::Object* array, mirror::Object* value,
+ Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
ThrowArrayStoreException(value->GetClass(), array->GetClass());
public:
explicit ConcurrentCopyingClearBlackPtrsVisitor(ConcurrentCopying* cc)
: collector_(cc) {}
+#ifndef USE_BAKER_OR_BROOKS_READ_BARRIER
+ NO_RETURN
+#endif
void operator()(mirror::Object* obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
DCHECK(obj != nullptr);
bool IsOnAllocStack(mirror::Object* ref) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::Object* GetFwdPtr(mirror::Object* from_ref)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FlipThreadRoots() LOCKS_EXCLUDED(Locks::mutator_lock_);;
+ void FlipThreadRoots() LOCKS_EXCLUDED(Locks::mutator_lock_);
void SwapStacks(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void RecordLiveStackFreezeSize(Thread* self);
void ComputeUnevacFromSpaceLiveRatio();
// Retry a second time with no specified request begin.
request_begin = nullptr;
}
- return nullptr;
}
bool Heap::MayUseCollector(CollectorType type) const {
}
}
UNREACHABLE();
- return nullptr;
}
void TaskProcessor::UpdateTargetRunTime(Thread* self, HeapTask* task, uint64_t new_target_time) {
void SetClass(Class* new_klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Object* GetReadBarrierPointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#ifndef USE_BAKER_OR_BROOKS_READ_BARRIER
+ NO_RETURN
+#endif
void SetReadBarrierPointer(Object* rb_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
}
UNREACHABLE();
- return false;
}
using M = RuntimeArgumentMap;
QuickExceptionHandler(Thread* self, bool is_deoptimization)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ~QuickExceptionHandler() {
+ NO_RETURN ~QuickExceptionHandler() {
LOG(FATAL) << "UNREACHABLE"; // Expected to take long jump.
UNREACHABLE();
}
break;
default:
return false;
- break;
}
return true;
}