diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 9092c3e0fa01f3139b016d05d267a89e3b07747a (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/Sema/SemaChecking.cpp | |
parent | 4981926bf654fe5a2c3893f24ca44106b217e71e (diff) | |
download | FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.zip FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.tar.gz |
Update clang to r84119.
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 530 |
1 files changed, 301 insertions, 229 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 4eed018..92bf83f 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements extra semantic analysis beyond what is enforced +// This file implements extra semantic analysis beyond what is enforced // by the C type system. // //===----------------------------------------------------------------------===// @@ -32,14 +32,14 @@ using namespace clang; SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const { assert(!SL->isWide() && "This doesn't work for wide strings yet"); - + // Loop over all of the tokens in this string until we find the one that // contains the byte we're looking for. unsigned TokNo = 0; while (1) { assert(TokNo < SL->getNumConcatenated() && "Invalid byte number!"); SourceLocation StrTokLoc = SL->getStrTokenLoc(TokNo); - + // Get the spelling of the string so that we can get the data that makes up // the string literal, not the identifier for the macro it is potentially // expanded through. @@ -51,65 +51,71 @@ SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL, std::pair<const char *,const char *> Buffer = SourceMgr.getBufferData(LocInfo.first); const char *StrData = Buffer.first+LocInfo.second; - + // Create a langops struct and enable trigraphs. This is sufficient for // relexing tokens. LangOptions LangOpts; LangOpts.Trigraphs = true; - + // Create a lexer starting at the beginning of this token. Lexer TheLexer(StrTokSpellingLoc, LangOpts, Buffer.first, StrData, Buffer.second); Token TheTok; TheLexer.LexFromRawLexer(TheTok); - + // Use the StringLiteralParser to compute the length of the string in bytes. StringLiteralParser SLP(&TheTok, 1, PP); unsigned TokNumBytes = SLP.GetStringLength(); - + // If the byte is in this token, return the location of the byte. if (ByteNo < TokNumBytes || (ByteNo == TokNumBytes && TokNo == SL->getNumConcatenated())) { - unsigned Offset = + unsigned Offset = StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP); - + // Now that we know the offset of the token in the spelling, use the // preprocessor to get the offset in the original source. return PP.AdvanceToTokenCharacter(StrTokLoc, Offset); } - + // Move to the next string token. ++TokNo; ByteNo -= TokNumBytes; } } +/// CheckablePrintfAttr - does a function call have a "printf" attribute +/// and arguments that merit checking? +bool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) { + if (Format->getType() == "printf") return true; + if (Format->getType() == "printf0") { + // printf0 allows null "format" string; if so don't check format/args + unsigned format_idx = Format->getFormatIdx() - 1; + if (format_idx < TheCall->getNumArgs()) { + Expr *Format = TheCall->getArg(format_idx)->IgnoreParenCasts(); + if (!Format->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) + return true; + } + } + return false; +} -/// CheckFunctionCall - Check a direct function call for various correctness -/// and safety properties not strictly enforced by the C type system. Action::OwningExprResult -Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { +Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { OwningExprResult TheCallResult(Owned(TheCall)); - // Get the IdentifierInfo* for the called function. - IdentifierInfo *FnInfo = FDecl->getIdentifier(); - - // None of the checks below are needed for functions that don't have - // simple names (e.g., C++ conversion functions). - if (!FnInfo) - return move(TheCallResult); - switch (FDecl->getBuiltinID(Context)) { + switch (BuiltinID) { case Builtin::BI__builtin___CFStringMakeConstantString: assert(TheCall->getNumArgs() == 1 && "Wrong # arguments to builtin CFStringMakeConstantString"); if (CheckObjCString(TheCall->getArg(0))) return ExprError(); - return move(TheCallResult); + break; case Builtin::BI__builtin_stdarg_start: case Builtin::BI__builtin_va_start: if (SemaBuiltinVAStart(TheCall)) return ExprError(); - return move(TheCallResult); + break; case Builtin::BI__builtin_isgreater: case Builtin::BI__builtin_isgreaterequal: case Builtin::BI__builtin_isless: @@ -118,12 +124,24 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { case Builtin::BI__builtin_isunordered: if (SemaBuiltinUnorderedCompare(TheCall)) return ExprError(); - return move(TheCallResult); + break; + case Builtin::BI__builtin_isfinite: + case Builtin::BI__builtin_isinf: + case Builtin::BI__builtin_isinf_sign: + case Builtin::BI__builtin_isnan: + case Builtin::BI__builtin_isnormal: + if (SemaBuiltinUnaryFP(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_return_address: case Builtin::BI__builtin_frame_address: if (SemaBuiltinStackAddress(TheCall)) return ExprError(); - return move(TheCallResult); + break; + case Builtin::BI__builtin_eh_return_data_regno: + if (SemaBuiltinEHReturnDataRegNo(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_shufflevector: return SemaBuiltinShuffleVector(TheCall); // TheCall will be freed by the smart pointer here, but that's fine, since @@ -131,15 +149,15 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { case Builtin::BI__builtin_prefetch: if (SemaBuiltinPrefetch(TheCall)) return ExprError(); - return move(TheCallResult); + break; case Builtin::BI__builtin_object_size: if (SemaBuiltinObjectSize(TheCall)) return ExprError(); - return move(TheCallResult); + break; case Builtin::BI__builtin_longjmp: if (SemaBuiltinLongjmp(TheCall)) return ExprError(); - return move(TheCallResult); + break; case Builtin::BI__sync_fetch_and_add: case Builtin::BI__sync_fetch_and_sub: case Builtin::BI__sync_fetch_and_or: @@ -158,61 +176,76 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { case Builtin::BI__sync_lock_release: if (SemaBuiltinAtomicOverloaded(TheCall)) return ExprError(); - return move(TheCallResult); + break; } + return move(TheCallResult); +} + +/// CheckFunctionCall - Check a direct function call for various correctness +/// and safety properties not strictly enforced by the C type system. +bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { + // Get the IdentifierInfo* for the called function. + IdentifierInfo *FnInfo = FDecl->getIdentifier(); + + // None of the checks below are needed for functions that don't have + // simple names (e.g., C++ conversion functions). + if (!FnInfo) + return false; + // FIXME: This mechanism should be abstracted to be less fragile and // more efficient. For example, just map function ids to custom // handlers. // Printf checking. if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) { - if (Format->getType() == "printf") { + if (CheckablePrintfAttr(Format, TheCall)) { bool HasVAListArg = Format->getFirstArg() == 0; if (!HasVAListArg) { - if (const FunctionProtoType *Proto - = FDecl->getType()->getAsFunctionProtoType()) + if (const FunctionProtoType *Proto + = FDecl->getType()->getAs<FunctionProtoType>()) HasVAListArg = !Proto->isVariadic(); } CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, HasVAListArg ? 0 : Format->getFirstArg() - 1); } } - for (const Attr *attr = FDecl->getAttrs(); - attr; attr = attr->getNext()) { - if (const NonNullAttr *NonNull = dyn_cast<NonNullAttr>(attr)) - CheckNonNullArguments(NonNull, TheCall); - } - return move(TheCallResult); -} + for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull; + NonNull = NonNull->getNext<NonNullAttr>()) + CheckNonNullArguments(NonNull, TheCall); -Action::OwningExprResult -Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) { + return false; +} - OwningExprResult TheCallResult(Owned(TheCall)); +bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) { // Printf checking. const FormatAttr *Format = NDecl->getAttr<FormatAttr>(); if (!Format) - return move(TheCallResult); + return false; + const VarDecl *V = dyn_cast<VarDecl>(NDecl); if (!V) - return move(TheCallResult); + return false; + QualType Ty = V->getType(); if (!Ty->isBlockPointerType()) - return move(TheCallResult); - if (Format->getType() == "printf") { - bool HasVAListArg = Format->getFirstArg() == 0; - if (!HasVAListArg) { - const FunctionType *FT = - Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType(); - if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) - HasVAListArg = !Proto->isVariadic(); - } - CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, - HasVAListArg ? 0 : Format->getFirstArg() - 1); + return false; + + if (!CheckablePrintfAttr(Format, TheCall)) + return false; + + bool HasVAListArg = Format->getFirstArg() == 0; + if (!HasVAListArg) { + const FunctionType *FT = + Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); + if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) + HasVAListArg = !Proto->isVariadic(); } - return move(TheCallResult); + CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, + HasVAListArg ? 0 : Format->getFirstArg() - 1); + + return false; } /// SemaBuiltinAtomicOverloaded - We have a call to a function like @@ -231,7 +264,7 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { if (TheCall->getNumArgs() < 1) return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) << 0 << TheCall->getCallee()->getSourceRange(); - + // Inspect the first argument of the atomic builtin. This should always be // a pointer type, whose element is an integral scalar or pointer type. // Because it is a pointer type, we don't have to worry about any implicit @@ -240,9 +273,9 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { if (!FirstArg->getType()->isPointerType()) return Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer) << FirstArg->getType() << FirstArg->getSourceRange(); - - QualType ValType = FirstArg->getType()->getAsPointerType()->getPointeeType(); - if (!ValType->isIntegerType() && !ValType->isPointerType() && + + QualType ValType = FirstArg->getType()->getAs<PointerType>()->getPointeeType(); + if (!ValType->isIntegerType() && !ValType->isPointerType() && !ValType->isBlockPointerType()) return Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer_intptr) @@ -254,7 +287,7 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { #define BUILTIN_ROW(x) \ { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \ Builtin::BI##x##_8, Builtin::BI##x##_16 } - + static const unsigned BuiltinIndices[][5] = { BUILTIN_ROW(__sync_fetch_and_add), BUILTIN_ROW(__sync_fetch_and_sub), @@ -262,21 +295,21 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { BUILTIN_ROW(__sync_fetch_and_and), BUILTIN_ROW(__sync_fetch_and_xor), BUILTIN_ROW(__sync_fetch_and_nand), - + BUILTIN_ROW(__sync_add_and_fetch), BUILTIN_ROW(__sync_sub_and_fetch), BUILTIN_ROW(__sync_and_and_fetch), BUILTIN_ROW(__sync_or_and_fetch), BUILTIN_ROW(__sync_xor_and_fetch), BUILTIN_ROW(__sync_nand_and_fetch), - + BUILTIN_ROW(__sync_val_compare_and_swap), BUILTIN_ROW(__sync_bool_compare_and_swap), BUILTIN_ROW(__sync_lock_test_and_set), BUILTIN_ROW(__sync_lock_release) }; -#undef BUILTIN_ROW - +#undef BUILTIN_ROW + // Determine the index of the size. unsigned SizeIndex; switch (Context.getTypeSize(ValType)/8) { @@ -289,12 +322,12 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { return Diag(DRE->getLocStart(), diag::err_atomic_builtin_pointer_size) << FirstArg->getType() << FirstArg->getSourceRange(); } - + // Each of these builtins has one pointer argument, followed by some number of // values (0, 1 or 2) followed by a potentially empty varags list of stuff // that we ignore. Find out which row of BuiltinIndices to read from as well // as the number of fixed args. - unsigned BuiltinID = FDecl->getBuiltinID(Context); + unsigned BuiltinID = FDecl->getBuiltinID(); unsigned BuiltinIndex, NumFixed = 1; switch (BuiltinID) { default: assert(0 && "Unknown overloaded atomic builtin!"); @@ -304,14 +337,14 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { case Builtin::BI__sync_fetch_and_and: BuiltinIndex = 3; break; case Builtin::BI__sync_fetch_and_xor: BuiltinIndex = 4; break; case Builtin::BI__sync_fetch_and_nand:BuiltinIndex = 5; break; - + case Builtin::BI__sync_add_and_fetch: BuiltinIndex = 6; break; case Builtin::BI__sync_sub_and_fetch: BuiltinIndex = 7; break; case Builtin::BI__sync_and_and_fetch: BuiltinIndex = 8; break; case Builtin::BI__sync_or_and_fetch: BuiltinIndex = 9; break; case Builtin::BI__sync_xor_and_fetch: BuiltinIndex =10; break; case Builtin::BI__sync_nand_and_fetch:BuiltinIndex =11; break; - + case Builtin::BI__sync_val_compare_and_swap: BuiltinIndex = 12; NumFixed = 2; @@ -326,36 +359,37 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { NumFixed = 0; break; } - + // Now that we know how many fixed arguments we expect, first check that we // have at least that many. if (TheCall->getNumArgs() < 1+NumFixed) return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) << 0 << TheCall->getCallee()->getSourceRange(); - - + + // Get the decl for the concrete builtin from this, we can tell what the // concrete integer type we should convert to is. unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; const char *NewBuiltinName = Context.BuiltinInfo.GetName(NewBuiltinID); IdentifierInfo *NewBuiltinII = PP.getIdentifierInfo(NewBuiltinName); - FunctionDecl *NewBuiltinDecl = + FunctionDecl *NewBuiltinDecl = cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID, TUScope, false, DRE->getLocStart())); const FunctionProtoType *BuiltinFT = - NewBuiltinDecl->getType()->getAsFunctionProtoType(); - ValType = BuiltinFT->getArgType(0)->getAsPointerType()->getPointeeType(); - + NewBuiltinDecl->getType()->getAs<FunctionProtoType>(); + ValType = BuiltinFT->getArgType(0)->getAs<PointerType>()->getPointeeType(); + // If the first type needs to be converted (e.g. void** -> int*), do it now. if (BuiltinFT->getArgType(0) != FirstArg->getType()) { - ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), false); + ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), CastExpr::CK_Unknown, + /*isLvalue=*/false); TheCall->setArg(0, FirstArg); } - + // Next, walk the valid ones promoting to the right type. for (unsigned i = 0; i != NumFixed; ++i) { Expr *Arg = TheCall->getArg(i+1); - + // If the argument is an implicit cast, then there was a promotion due to // "...", just remove it now. if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { @@ -364,32 +398,35 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { ICE->Destroy(Context); TheCall->setArg(i+1, Arg); } - + // GCC does an implicit conversion to the pointer or integer ValType. This // can fail in some cases (1i -> int**), check for this error case now. - if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg)) + CastExpr::CastKind Kind = CastExpr::CK_Unknown; + CXXMethodDecl *ConversionDecl = 0; + if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, + ConversionDecl)) return true; - + // Okay, we have something that *can* be converted to the right type. Check // to see if there is a potentially weird extension going on here. This can // happen when you do an atomic operation on something like an char* and // pass in 42. The 42 gets converted to char. This is even more strange // for things like 45.123 -> char, etc. - // FIXME: Do this check. - ImpCastExprToType(Arg, ValType, false); + // FIXME: Do this check. + ImpCastExprToType(Arg, ValType, Kind, /*isLvalue=*/false); TheCall->setArg(i+1, Arg); } - + // Switch the DeclRefExpr to refer to the new decl. DRE->setDecl(NewBuiltinDecl); DRE->setType(NewBuiltinDecl->getType()); - + // Set the callee in the CallExpr. // FIXME: This leaks the original parens and implicit casts. Expr *PromotedCall = DRE; UsualUnaryConversions(PromotedCall); TheCall->setCallee(PromotedCall); - + // Change the result type of the call to match the result type of the decl. TheCall->setType(NewBuiltinDecl->getResultType()); @@ -400,7 +437,7 @@ bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) { /// CheckObjCString - Checks that the argument to the builtin /// CFString constructor is correct /// FIXME: GCC currently emits the following warning: -/// "warning: input conversion stopped due to an input byte that does not +/// "warning: input conversion stopped due to an input byte that does not /// belong to the input codeset UTF-8" /// Note: It might also make sense to do the UTF-16 conversion here (would /// simplify the backend). @@ -413,10 +450,10 @@ bool Sema::CheckObjCString(Expr *Arg) { << Arg->getSourceRange(); return true; } - + const char *Data = Literal->getStrData(); unsigned Length = Literal->getByteLength(); - + for (unsigned i = 0; i < Length; ++i) { if (!Data[i]) { Diag(getLocationOfStringLiteralByte(Literal, i), @@ -425,7 +462,7 @@ bool Sema::CheckObjCString(Expr *Arg) { break; } } - + return false; } @@ -437,7 +474,7 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { Diag(TheCall->getArg(2)->getLocStart(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << Fn->getSourceRange() - << SourceRange(TheCall->getArg(2)->getLocStart(), + << SourceRange(TheCall->getArg(2)->getLocStart(), (*(TheCall->arg_end()-1))->getLocEnd()); return true; } @@ -460,17 +497,17 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { } else { isVariadic = getCurMethodDecl()->isVariadic(); } - + if (!isVariadic) { Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function); return true; } - + // Verify that the second argument to the builtin is the last argument of the // current function or method. bool SecondArgIsLastNamedArgument = false; const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts(); - + if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) { if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { // FIXME: This isn't correct for methods (results in bogus warning). @@ -485,9 +522,9 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { SecondArgIsLastNamedArgument = PV == LastArg; } } - + if (!SecondArgIsLastNamedArgument) - Diag(TheCall->getArg(1)->getLocStart(), + Diag(TheCall->getArg(1)->getLocStart(), diag::warn_second_parameter_of_va_start_not_last_named_argument); return false; } @@ -499,12 +536,12 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) << 0 /*function call*/; if (TheCall->getNumArgs() > 2) - return Diag(TheCall->getArg(2)->getLocStart(), + return Diag(TheCall->getArg(2)->getLocStart(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << SourceRange(TheCall->getArg(2)->getLocStart(), (*(TheCall->arg_end()-1))->getLocEnd()); - + Expr *OrigArg0 = TheCall->getArg(0); Expr *OrigArg1 = TheCall->getArg(1); @@ -517,18 +554,45 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { // foo(...)". TheCall->setArg(0, OrigArg0); TheCall->setArg(1, OrigArg1); - + if (OrigArg0->isTypeDependent() || OrigArg1->isTypeDependent()) return false; // If the common type isn't a real floating type, then the arguments were // invalid for this operation. if (!Res->isRealFloatingType()) - return Diag(OrigArg0->getLocStart(), + return Diag(OrigArg0->getLocStart(), diag::err_typecheck_call_invalid_ordered_compare) << OrigArg0->getType() << OrigArg1->getType() << SourceRange(OrigArg0->getLocStart(), OrigArg1->getLocEnd()); - + + return false; +} + +/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isnan and +/// friends. This is declared to take (...), so we have to check everything. +bool Sema::SemaBuiltinUnaryFP(CallExpr *TheCall) { + if (TheCall->getNumArgs() < 1) + return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) + << 0 /*function call*/; + if (TheCall->getNumArgs() > 1) + return Diag(TheCall->getArg(1)->getLocStart(), + diag::err_typecheck_call_too_many_args) + << 0 /*function call*/ + << SourceRange(TheCall->getArg(1)->getLocStart(), + (*(TheCall->arg_end()-1))->getLocEnd()); + + Expr *OrigArg = TheCall->getArg(0); + + if (OrigArg->isTypeDependent()) + return false; + + // This operation requires a floating-point number + if (!OrigArg->getType()->isRealFloatingType()) + return Diag(OrigArg->getLocStart(), + diag::err_typecheck_call_invalid_unary_fp) + << OrigArg->getType() << OrigArg->getSourceRange(); + return false; } @@ -540,7 +604,7 @@ bool Sema::SemaBuiltinStackAddress(CallExpr *TheCall) { !TheCall->getArg(0)->isValueDependent() && !TheCall->getArg(0)->isIntegerConstantExpr(Context, &Loc)) return Diag(Loc, diag::err_stack_const_level) << TheCall->getSourceRange(); - + return false; } @@ -557,23 +621,23 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { !TheCall->getArg(1)->isTypeDependent()) { QualType FAType = TheCall->getArg(0)->getType(); QualType SAType = TheCall->getArg(1)->getType(); - + if (!FAType->isVectorType() || !SAType->isVectorType()) { Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector) - << SourceRange(TheCall->getArg(0)->getLocStart(), + << SourceRange(TheCall->getArg(0)->getLocStart(), TheCall->getArg(1)->getLocEnd()); return ExprError(); } - + if (Context.getCanonicalType(FAType).getUnqualifiedType() != Context.getCanonicalType(SAType).getUnqualifiedType()) { Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) - << SourceRange(TheCall->getArg(0)->getLocStart(), + << SourceRange(TheCall->getArg(0)->getLocStart(), TheCall->getArg(1)->getLocEnd()); return ExprError(); } - numElements = FAType->getAsVectorType()->getNumElements(); + numElements = FAType->getAs<VectorType>()->getNumElements(); if (TheCall->getNumArgs() != numElements+2) { if (TheCall->getNumArgs() < numElements+2) return ExprError(Diag(TheCall->getLocEnd(), @@ -609,8 +673,8 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { TheCall->setArg(i, 0); } - return Owned(new (Context) ShuffleVectorExpr(exprs.begin(), exprs.size(), - exprs[0]->getType(), + return Owned(new (Context) ShuffleVectorExpr(Context, exprs.begin(), + exprs.size(), exprs[0]->getType(), TheCall->getCallee()->getLocStart(), TheCall->getRParenLoc())); } @@ -634,11 +698,11 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { QualType RWType = Arg->getType(); - const BuiltinType *BT = RWType->getAsBuiltinType(); + const BuiltinType *BT = RWType->getAs<BuiltinType>(); llvm::APSInt Result; if (!BT || BT->getKind() != BuiltinType::Int) return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument) - << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + << Arg->getSourceRange(); if (Arg->isValueDependent()) continue; @@ -646,24 +710,36 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { if (!Arg->isIntegerConstantExpr(Result, Context)) return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument) << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); - + // FIXME: gcc issues a warning and rewrites these to 0. These // seems especially odd for the third argument since the default // is 3. if (i == 1) { if (Result.getSExtValue() < 0 || Result.getSExtValue() > 1) return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) - << "0" << "1" << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + << "0" << "1" << Arg->getSourceRange(); } else { if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) - << "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + << "0" << "3" << Arg->getSourceRange(); } } return false; } +/// SemaBuiltinEHReturnDataRegNo - Handle __builtin_eh_return_data_regno, the +/// operand must be an integer constant. +bool Sema::SemaBuiltinEHReturnDataRegNo(CallExpr *TheCall) { + llvm::APSInt Result; + if (!TheCall->getArg(0)->isIntegerConstantExpr(Result, Context)) + return Diag(TheCall->getLocStart(), diag::err_expr_not_ice) + << TheCall->getArg(0)->getSourceRange(); + + return false; +} + + /// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr, /// int type). This simply type checks that type is one of the defined /// constants (0-3). @@ -672,8 +748,8 @@ bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) { if (Arg->isTypeDependent()) return false; - QualType ArgType = Arg->getType(); - const BuiltinType *BT = ArgType->getAsBuiltinType(); + QualType ArgType = Arg->getType(); + const BuiltinType *BT = ArgType->getAs<BuiltinType>(); llvm::APSInt Result(32); if (!BT || BT->getKind() != BuiltinType::Int) return Diag(TheCall->getLocStart(), diag::err_object_size_invalid_argument) @@ -737,10 +813,10 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg, format_idx, firstDataArg); } - + case Stmt::DeclRefExprClass: { const DeclRefExpr *DR = cast<DeclRefExpr>(E); - + // As an exception, do not flag errors for variables binding to // const string literals. if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { @@ -749,19 +825,18 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, if (const ArrayType *AT = Context.getAsArrayType(T)) { isConstant = AT->getElementType().isConstant(Context); - } - else if (const PointerType *PT = T->getAsPointerType()) { - isConstant = T.isConstant(Context) && + } else if (const PointerType *PT = T->getAs<PointerType>()) { + isConstant = T.isConstant(Context) && PT->getPointeeType().isConstant(Context); } - + if (isConstant) { const VarDecl *Def = 0; if (const Expr *Init = VD->getDefinition(Def)) return SemaCheckStringLiteral(Init, TheCall, HasVAListArg, format_idx, firstDataArg); } - + // For vprintf* functions (i.e., HasVAListArg==true), we add a // special check to see if the format string is a function parameter // of the function calling the printf function. If the function @@ -784,66 +859,67 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, if (isa<ParmVarDecl>(VD)) return true; } - + return false; } case Stmt::CallExprClass: { const CallExpr *CE = cast<CallExpr>(E); - if (const ImplicitCastExpr *ICE + if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE->getCallee())) { if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) { if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) { if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) { unsigned ArgIndex = FA->getFormatIdx(); const Expr *Arg = CE->getArg(ArgIndex - 1); - - return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg, + + return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg, format_idx, firstDataArg); } } } } - + return false; } case Stmt::ObjCStringLiteralClass: case Stmt::StringLiteralClass: { const StringLiteral *StrE = NULL; - + if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E)) StrE = ObjCFExpr->getString(); else StrE = cast<StringLiteral>(E); - + if (StrE) { - CheckPrintfString(StrE, E, TheCall, HasVAListArg, format_idx, + CheckPrintfString(StrE, E, TheCall, HasVAListArg, format_idx, firstDataArg); return true; } - + return false; } - + default: return false; } } void -Sema::CheckNonNullArguments(const NonNullAttr *NonNull, const CallExpr *TheCall) -{ +Sema::CheckNonNullArguments(const NonNullAttr *NonNull, + const CallExpr *TheCall) { for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end(); i != e; ++i) { const Expr *ArgExpr = TheCall->getArg(*i); - if (ArgExpr->isNullPointerConstant(Context)) + if (ArgExpr->isNullPointerConstant(Context, + Expr::NPC_ValueDependentIsNotNull)) Diag(TheCall->getCallee()->getLocStart(), diag::warn_null_arg) << ArgExpr->getSourceRange(); } } /// CheckPrintfArguments - Check calls to printf (and similar functions) for -/// correct use of format strings. +/// correct use of format strings. /// /// HasVAListArg - A predicate indicating whether the printf-like /// function is passed an explicit va_arg argument (e.g., vprintf) @@ -892,30 +968,30 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull, const CallExpr *TheCall) /// /// For now, we ONLY do (1), (3), (5), (6), (7), and (8). void -Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg, +Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg) { const Expr *Fn = TheCall->getCallee(); - // CHECK: printf-like function is called with no format string. + // CHECK: printf-like function is called with no format string. if (format_idx >= TheCall->getNumArgs()) { Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string) << Fn->getSourceRange(); return; } - + const Expr *OrigFormatExpr = TheCall->getArg(format_idx)->IgnoreParenCasts(); - + // CHECK: format string is not a string literal. - // + // // Dynamically generated format strings are difficult to // automatically vet at compile time. Requiring that format strings // are string literals: (1) permits the checking of format strings by // the compiler and thereby (2) can practically remove the source of // many format string exploits. - // Format string can be either ObjC string (e.g. @"%d") or + // Format string can be either ObjC string (e.g. @"%d") or // C string (e.g. "%d") - // ObjC string uses the same format specifiers as C string, so we can use + // ObjC string uses the same format specifiers as C string, so we can use // the same format string checking logic for both ObjC and C strings. if (SemaCheckStringLiteral(OrigFormatExpr, TheCall, HasVAListArg, format_idx, firstDataArg)) @@ -924,11 +1000,11 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg, // If there are no arguments specified, warn with -Wformat-security, otherwise // warn only with -Wformat-nonliteral. if (TheCall->getNumArgs() == format_idx+1) - Diag(TheCall->getArg(format_idx)->getLocStart(), + Diag(TheCall->getArg(format_idx)->getLocStart(), diag::warn_printf_nonliteral_noargs) << OrigFormatExpr->getSourceRange(); else - Diag(TheCall->getArg(format_idx)->getLocStart(), + Diag(TheCall->getArg(format_idx)->getLocStart(), diag::warn_printf_nonliteral) << OrigFormatExpr->getSourceRange(); } @@ -954,7 +1030,7 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, // CHECK: empty format string? unsigned StrLen = FExpr->getByteLength(); - + if (StrLen == 0) { Diag(FExpr->getLocStart(), diag::warn_printf_empty_format_string) << OrigFormatExpr->getSourceRange(); @@ -967,7 +1043,7 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, state_OrdChr, state_Conversion } CurrentState = state_OrdChr; - + // numConversions - The number of conversions seen so far. This is // incremented as we traverse the format string. unsigned numConversions = 0; @@ -980,17 +1056,17 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, // Inspect the format string. unsigned StrIdx = 0; - + // LastConversionIdx - Index within the format string where we last saw // a '%' character that starts a new format conversion. unsigned LastConversionIdx = 0; - + for (; StrIdx < StrLen; ++StrIdx) { - + // Is the number of detected conversion conversions greater than // the number of matching data arguments? If so, stop. if (!HasVAListArg && numConversions > numDataArgs) break; - + // Handle "\0" if (Str[StrIdx] == '\0') { // The string returned by getStrData() is not null-terminated, @@ -1000,7 +1076,7 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, << OrigFormatExpr->getSourceRange(); return; } - + // Ordinary characters (not processing a format conversion). if (CurrentState == state_OrdChr) { if (Str[StrIdx] == '%') { @@ -1012,10 +1088,10 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, // Seen '%'. Now processing a format conversion. switch (Str[StrIdx]) { - // Handle dynamic precision or width specifier. + // Handle dynamic precision or width specifier. case '*': { ++numConversions; - + if (!HasVAListArg) { if (numConversions > numDataArgs) { SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, StrIdx); @@ -1026,39 +1102,39 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, else Diag(Loc, diag::warn_printf_asterisk_width_missing_arg) << OrigFormatExpr->getSourceRange(); - + // Don't do any more checking. We'll just emit spurious errors. return; } - + // Perform type checking on width/precision specifier. const Expr *E = TheCall->getArg(format_idx+numConversions); - if (const BuiltinType *BT = E->getType()->getAsBuiltinType()) + if (const BuiltinType *BT = E->getType()->getAs<BuiltinType>()) if (BT->getKind() == BuiltinType::Int) break; - + SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, StrIdx); - + if (Str[StrIdx-1] == '.') Diag(Loc, diag::warn_printf_asterisk_precision_wrong_type) << E->getType() << E->getSourceRange(); else Diag(Loc, diag::warn_printf_asterisk_width_wrong_type) << E->getType() << E->getSourceRange(); - - break; + + break; } } - + // Characters which can terminate a format conversion // (e.g. "%d"). Characters that specify length modifiers or // other flags are handled by the default case below. // - // FIXME: additional checks will go into the following cases. + // FIXME: additional checks will go into the following cases. case 'i': case 'd': - case 'o': - case 'u': + case 'o': + case 'u': case 'x': case 'X': case 'D': @@ -1076,7 +1152,7 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, case 'C': case 'S': case 's': - case 'p': + case 'p': ++numConversions; CurrentState = state_OrdChr; break; @@ -1092,21 +1168,21 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, CurrentState = state_OrdChr; SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, LastConversionIdx); - + Diag(Loc, diag::warn_printf_write_back)<<OrigFormatExpr->getSourceRange(); break; } - + // Handle "%@" case '@': // %@ is allowed in ObjC format strings only. - if(ObjCFExpr != NULL) - CurrentState = state_OrdChr; + if (ObjCFExpr != NULL) + CurrentState = state_OrdChr; else { // Issue a warning: invalid format conversion. - SourceLocation Loc = + SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, LastConversionIdx); - + Diag(Loc, diag::warn_printf_invalid_conversion) << std::string(Str+LastConversionIdx, Str+std::min(LastConversionIdx+2, StrLen)) @@ -1114,7 +1190,7 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, } ++numConversions; break; - + // Handle "%%" case '%': // Sanity check: Was the first "%" character the previous one? @@ -1122,23 +1198,23 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, // conversion, and that the current "%" character is the start // of a new conversion. if (StrIdx - LastConversionIdx == 1) - CurrentState = state_OrdChr; + CurrentState = state_OrdChr; else { // Issue a warning: invalid format conversion. SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, LastConversionIdx); - + Diag(Loc, diag::warn_printf_invalid_conversion) << std::string(Str+LastConversionIdx, Str+StrIdx) << OrigFormatExpr->getSourceRange(); - + // This conversion is broken. Advance to the next format // conversion. LastConversionIdx = StrIdx; ++numConversions; } break; - + default: // This case catches all other characters: flags, widths, etc. // We should eventually process those as well. @@ -1150,21 +1226,21 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, // Issue a warning: invalid format conversion. SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, LastConversionIdx); - + Diag(Loc, diag::warn_printf_invalid_conversion) << std::string(Str+LastConversionIdx, Str+std::min(LastConversionIdx+2, StrLen)) << OrigFormatExpr->getSourceRange(); return; } - + if (!HasVAListArg) { // CHECK: Does the number of format conversions exceed the number // of data arguments? if (numConversions > numDataArgs) { SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, LastConversionIdx); - + Diag(Loc, diag::warn_printf_insufficient_data_args) << OrigFormatExpr->getSourceRange(); } @@ -1187,25 +1263,22 @@ static DeclRefExpr* EvalAddr(Expr* E); void Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc) { - + // Perform checking for returned stack addresses. if (lhsType->isPointerType() || lhsType->isBlockPointerType()) { if (DeclRefExpr *DR = EvalAddr(RetValExp)) Diag(DR->getLocStart(), diag::warn_ret_stack_addr) << DR->getDecl()->getDeclName() << RetValExp->getSourceRange(); - + // Skip over implicit cast expressions when checking for block expressions. - if (ImplicitCastExpr *IcExpr = - dyn_cast_or_null<ImplicitCastExpr>(RetValExp)) - RetValExp = IcExpr->getSubExpr(); + RetValExp = RetValExp->IgnoreParenCasts(); if (BlockExpr *C = dyn_cast_or_null<BlockExpr>(RetValExp)) if (C->hasBlockDeclRefExprs()) Diag(C->getLocStart(), diag::err_ret_local_block) << C->getSourceRange(); - } - // Perform checking for stack values returned by reference. - else if (lhsType->isReferenceType()) { + } else if (lhsType->isReferenceType()) { + // Perform checking for stack values returned by reference. // Check for a reference to the stack if (DeclRefExpr *DR = EvalVal(RetValExp)) Diag(DR->getLocStart(), diag::warn_ret_stack_ref) @@ -1223,7 +1296,7 @@ Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, /// /// EvalAddr processes expressions that are pointers that are used as /// references (and not L-values). EvalVal handles all other values. -/// At the base case of the recursion is a check for a DeclRefExpr* in +/// At the base case of the recursion is a check for a DeclRefExpr* in /// the refers to a stack variable. /// /// This implementation handles: @@ -1236,11 +1309,11 @@ Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, /// * taking the address of an array element where the array is on the stack static DeclRefExpr* EvalAddr(Expr *E) { // We should only be called for evaluating pointer expressions. - assert((E->getType()->isPointerType() || + assert((E->getType()->isAnyPointerType() || E->getType()->isBlockPointerType() || E->getType()->isObjCQualifiedIdType()) && "EvalAddr only works on pointers"); - + // Our "symbolic interpreter" is just a dispatch off the currently // viewed AST node. We then recursively traverse the AST by calling // EvalAddr and EvalVal appropriately. @@ -1253,28 +1326,28 @@ static DeclRefExpr* EvalAddr(Expr *E) { // The only unary operator that make sense to handle here // is AddrOf. All others don't make sense as pointers. UnaryOperator *U = cast<UnaryOperator>(E); - + if (U->getOpcode() == UnaryOperator::AddrOf) return EvalVal(U->getSubExpr()); else return NULL; } - + case Stmt::BinaryOperatorClass: { // Handle pointer arithmetic. All other binary operators are not valid // in this context. BinaryOperator *B = cast<BinaryOperator>(E); BinaryOperator::Opcode op = B->getOpcode(); - + if (op != BinaryOperator::Add && op != BinaryOperator::Sub) return NULL; - + Expr *Base = B->getLHS(); // Determine which argument is the real pointer base. It could be // the RHS argument instead of the LHS. if (!Base->getType()->isPointerType()) Base = B->getRHS(); - + assert (Base->getType()->isPointerType()); return EvalAddr(Base); } @@ -1283,7 +1356,7 @@ static DeclRefExpr* EvalAddr(Expr *E) { // valid DeclRefExpr*s. If one of them is valid, we return it. case Stmt::ConditionalOperatorClass: { ConditionalOperator *C = cast<ConditionalOperator>(E); - + // Handle the GNU extension for missing LHS. if (Expr *lhsExpr = C->getLHS()) if (DeclRefExpr* LHS = EvalAddr(lhsExpr)) @@ -1291,7 +1364,7 @@ static DeclRefExpr* EvalAddr(Expr *E) { return EvalAddr(C->getRHS()); } - + // For casts, we need to handle conversions from arrays to // pointer values, and pointer-to-pointer conversions. case Stmt::ImplicitCastExprClass: @@ -1299,7 +1372,7 @@ static DeclRefExpr* EvalAddr(Expr *E) { case Stmt::CXXFunctionalCastExprClass: { Expr* SubExpr = cast<CastExpr>(E)->getSubExpr(); QualType T = SubExpr->getType(); - + if (SubExpr->getType()->isPointerType() || SubExpr->getType()->isBlockPointerType() || SubExpr->getType()->isObjCQualifiedIdType()) @@ -1309,7 +1382,7 @@ static DeclRefExpr* EvalAddr(Expr *E) { else return 0; } - + // C++ casts. For dynamic casts, static casts, and const casts, we // are always converting from a pointer-to-pointer, so we just blow // through the cast. In the case the dynamic cast doesn't fail (and @@ -1317,9 +1390,9 @@ static DeclRefExpr* EvalAddr(Expr *E) { // where we return the address of a stack variable. For Reinterpre // FIXME: The comment about is wrong; we're not always converting // from pointer to pointer. I'm guessing that this code should also - // handle references to objects. - case Stmt::CXXStaticCastExprClass: - case Stmt::CXXDynamicCastExprClass: + // handle references to objects. + case Stmt::CXXStaticCastExprClass: + case Stmt::CXXDynamicCastExprClass: case Stmt::CXXConstCastExprClass: case Stmt::CXXReinterpretCastExprClass: { Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr(); @@ -1328,62 +1401,62 @@ static DeclRefExpr* EvalAddr(Expr *E) { else return NULL; } - + // Everything else: we simply don't reason about them. default: return NULL; } } - + /// EvalVal - This function is complements EvalAddr in the mutual recursion. /// See the comments for EvalAddr for more details. static DeclRefExpr* EvalVal(Expr *E) { - + // We should only be called for evaluating non-pointer expressions, or // expressions with a pointer type that are not used as references but instead // are l-values (e.g., DeclRefExpr with a pointer type). - + // Our "symbolic interpreter" is just a dispatch off the currently // viewed AST node. We then recursively traverse the AST by calling // EvalAddr and EvalVal appropriately. switch (E->getStmtClass()) { - case Stmt::DeclRefExprClass: + case Stmt::DeclRefExprClass: case Stmt::QualifiedDeclRefExprClass: { // DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking // at code that refers to a variable's name. We check if it has local // storage within the function, and if so, return the expression. DeclRefExpr *DR = cast<DeclRefExpr>(E); - + if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) - if(V->hasLocalStorage() && !V->getType()->isReferenceType()) return DR; - + if (V->hasLocalStorage() && !V->getType()->isReferenceType()) return DR; + return NULL; } - + case Stmt::ParenExprClass: // Ignore parentheses. return EvalVal(cast<ParenExpr>(E)->getSubExpr()); - + case Stmt::UnaryOperatorClass: { // The only unary operator that make sense to handle here // is Deref. All others don't resolve to a "name." This includes // handling all sorts of rvalues passed to a unary operator. UnaryOperator *U = cast<UnaryOperator>(E); - + if (U->getOpcode() == UnaryOperator::Deref) return EvalAddr(U->getSubExpr()); return NULL; } - + case Stmt::ArraySubscriptExprClass: { // Array subscripts are potential references to data on the stack. We // retrieve the DeclRefExpr* for the array variable if it indeed // has local storage. return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase()); } - + case Stmt::ConditionalOperatorClass: { // For conditional operators we need to see if either the LHS or RHS are // non-NULL DeclRefExpr's. If one is non-NULL, we return it. @@ -1396,18 +1469,18 @@ static DeclRefExpr* EvalVal(Expr *E) { return EvalVal(C->getRHS()); } - + // Accesses to members are potential references to data on the stack. case Stmt::MemberExprClass: { MemberExpr *M = cast<MemberExpr>(E); - + // Check for indirect access. We only want direct field accesses. if (!M->isArrow()) return EvalVal(M->getBase()); else return NULL; } - + // Everything else: we simply don't reason about them. default: return NULL; @@ -1421,7 +1494,7 @@ static DeclRefExpr* EvalVal(Expr *E) { /// to do what the programmer intended. void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) { bool EmitWarning = true; - + Expr* LeftExprSansParen = lex->IgnoreParens(); Expr* RightExprSansParen = rex->IgnoreParens(); @@ -1431,8 +1504,8 @@ void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) { if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen)) if (DRL->getDecl() == DRR->getDecl()) EmitWarning = false; - - + + // Special case: check for comparisons against literals that can be exactly // represented by APFloat. In such cases, do not emit a warning. This // is a heuristic: often comparison against such literals are used to @@ -1442,25 +1515,24 @@ void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) { if (FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) { if (FLL->isExact()) EmitWarning = false; - } - else + } else if (FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen)){ if (FLR->isExact()) EmitWarning = false; } } - + // Check for comparisons with builtin types. if (EmitWarning) if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen)) if (CL->isBuiltinCall(Context)) EmitWarning = false; - + if (EmitWarning) if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen)) if (CR->isBuiltinCall(Context)) EmitWarning = false; - + // Emit the diagnostic. if (EmitWarning) Diag(loc, diag::warn_floatingpoint_eq) |