aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp806
1 files changed, 549 insertions, 257 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index a0b4b988dbeb..556665483e64 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -25,82 +25,23 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
-#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/ConvertUTF.h"
#include <limits>
using namespace clang;
using namespace sema;
-/// getLocationOfStringLiteralByte - Return a source location that points to the
-/// specified byte of the specified string literal.
-///
-/// Strings are amazingly complex. They can be formed from multiple tokens and
-/// can have escape sequences in them in addition to the usual trigraph and
-/// escaped newline business. This routine handles this complexity.
-///
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.
- SourceLocation StrTokSpellingLoc = SourceMgr.getSpellingLoc(StrTokLoc);
-
- // Re-lex the token to get its length and original spelling.
- std::pair<FileID, unsigned> LocInfo =
- SourceMgr.getDecomposedLoc(StrTokSpellingLoc);
- bool Invalid = false;
- llvm::StringRef Buffer = SourceMgr.getBufferData(LocInfo.first, &Invalid);
- if (Invalid)
- return StrTokSpellingLoc;
-
- const char *StrData = Buffer.data()+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.begin(), StrData,
- Buffer.end());
- Token TheTok;
- TheLexer.LexFromRawLexer(TheTok);
-
- // Use the StringLiteralParser to compute the length of the string in bytes.
- StringLiteralParser SLP(&TheTok, 1, PP, /*Complain=*/false);
- 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 =
- StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP,
- /*Complain=*/false);
-
- // 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;
- }
+ return SL->getLocationOfByte(ByteNo, PP.getSourceManager(),
+ PP.getLangOptions(), PP.getTargetInfo());
}
+
/// CheckablePrintfAttr - does a function call have a "printf" attribute
/// and arguments that merit checking?
@@ -129,6 +70,24 @@ ExprResult
Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
ExprResult TheCallResult(Owned(TheCall));
+ // Find out if any arguments are required to be integer constant expressions.
+ unsigned ICEArguments = 0;
+ ASTContext::GetBuiltinTypeError Error;
+ Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);
+ if (Error != ASTContext::GE_None)
+ ICEArguments = 0; // Don't diagnose previously diagnosed errors.
+
+ // If any arguments are required to be ICE's, check and diagnose.
+ for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
+ // Skip arguments not required to be ICE's.
+ if ((ICEArguments & (1 << ArgNo)) == 0) continue;
+
+ llvm::APSInt Result;
+ if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
+ return true;
+ ICEArguments &= ~(1 << ArgNo);
+ }
+
switch (BuiltinID) {
case Builtin::BI__builtin___CFStringMakeConstantString:
assert(TheCall->getNumArgs() == 1 &&
@@ -162,19 +121,6 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
if (SemaBuiltinFPClassification(TheCall, 1))
return ExprError();
break;
- case Builtin::BI__builtin_return_address:
- case Builtin::BI__builtin_frame_address: {
- llvm::APSInt Result;
- if (SemaBuiltinConstantArg(TheCall, 0, Result))
- return ExprError();
- break;
- }
- case Builtin::BI__builtin_eh_return_data_regno: {
- llvm::APSInt Result;
- if (SemaBuiltinConstantArg(TheCall, 0, Result))
- 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
@@ -191,6 +137,16 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
if (SemaBuiltinLongjmp(TheCall))
return ExprError();
break;
+ case Builtin::BI__builtin_constant_p:
+ if (TheCall->getNumArgs() == 0)
+ return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
+ << 0 /*function call*/ << 1 << 0 << TheCall->getSourceRange();
+ if (TheCall->getNumArgs() > 1)
+ return Diag(TheCall->getArg(1)->getLocStart(),
+ diag::err_typecheck_call_too_many_args)
+ << 0 /*function call*/ << 1 << TheCall->getNumArgs()
+ << TheCall->getArg(1)->getSourceRange();
+ break;
case Builtin::BI__sync_fetch_and_add:
case Builtin::BI__sync_fetch_and_sub:
case Builtin::BI__sync_fetch_and_or:
@@ -217,11 +173,6 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall))
return ExprError();
break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (CheckX86BuiltinFunctionCall(BuiltinID, TheCall))
- return ExprError();
- break;
default:
break;
}
@@ -230,19 +181,6 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return move(TheCallResult);
}
-bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
- switch (BuiltinID) {
- case X86::BI__builtin_ia32_palignr128:
- case X86::BI__builtin_ia32_palignr: {
- llvm::APSInt Result;
- if (SemaBuiltinConstantArg(TheCall, 2, Result))
- return true;
- break;
- }
- }
- return false;
-}
-
// Get the valid immediate range for the specified NEON type code.
static unsigned RFT(unsigned t, bool shift = false) {
bool quad = t & 0x10;
@@ -260,11 +198,9 @@ static unsigned RFT(unsigned t, bool shift = false) {
assert(!shift && "cannot shift float types!");
return (2 << (int)quad) - 1;
case 5: // poly8
- assert(!shift && "cannot shift polynomial types!");
- return (8 << (int)quad) - 1;
+ return shift ? 7 : (8 << (int)quad) - 1;
case 6: // poly16
- assert(!shift && "cannot shift polynomial types!");
- return (4 << (int)quad) - 1;
+ return shift ? 15 : (4 << (int)quad) - 1;
case 7: // float16
assert(!shift && "cannot shift float types!");
return (4 << (int)quad) - 1;
@@ -339,8 +275,12 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
// more efficient. For example, just map function ids to custom
// handlers.
- // Printf checking.
- if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
+ // Printf and scanf checking.
+ for (specific_attr_iterator<FormatAttr>
+ i = FDecl->specific_attr_begin<FormatAttr>(),
+ e = FDecl->specific_attr_end<FormatAttr>(); i != e ; ++i) {
+
+ const FormatAttr *Format = *i;
const bool b = Format->getType() == "scanf";
if (b || CheckablePrintfAttr(Format, TheCall)) {
bool HasVAListArg = Format->getFirstArg() == 0;
@@ -351,12 +291,11 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
}
}
- specific_attr_iterator<NonNullAttr>
- i = FDecl->specific_attr_begin<NonNullAttr>(),
- e = FDecl->specific_attr_end<NonNullAttr>();
-
- for (; i != e; ++i)
+ for (specific_attr_iterator<NonNullAttr>
+ i = FDecl->specific_attr_begin<NonNullAttr>(),
+ e = FDecl->specific_attr_end<NonNullAttr>(); i != e; ++i) {
CheckNonNullArguments(*i, TheCall);
+ }
return false;
}
@@ -422,7 +361,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
QualType ValType =
FirstArg->getType()->getAs<PointerType>()->getPointeeType();
- if (!ValType->isIntegerType() && !ValType->isPointerType() &&
+ if (!ValType->isIntegerType() && !ValType->isAnyPointerType() &&
!ValType->isBlockPointerType()) {
Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer_intptr)
<< FirstArg->getType() << FirstArg->getSourceRange();
@@ -545,9 +484,10 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
// 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.
- CastKind Kind = CK_Unknown;
+ CastKind Kind = CK_Invalid;
+ ExprValueKind VK = VK_RValue;
CXXCastPath BasePath;
- if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath))
+ if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, VK, BasePath))
return ExprError();
// Okay, we have something that *can* be converted to the right type. Check
@@ -556,7 +496,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
// 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, Kind, VK_RValue, &BasePath);
+ ImpCastExprToType(Arg, ValType, Kind, VK, &BasePath);
TheCall->setArg(i+1, Arg);
}
@@ -581,9 +521,6 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
/// 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
-/// belong to the input codeset UTF-8"
/// Note: It might also make sense to do the UTF-16 conversion here (would
/// simplify the backend).
bool Sema::CheckObjCString(Expr *Arg) {
@@ -602,7 +539,21 @@ bool Sema::CheckObjCString(Expr *Arg) {
diag::warn_cfstring_literal_contains_nul_character)
<< Arg->getSourceRange();
}
-
+ if (Literal->containsNonAsciiOrNull()) {
+ llvm::StringRef String = Literal->getString();
+ unsigned NumBytes = String.size();
+ llvm::SmallVector<UTF16, 128> ToBuf(NumBytes);
+ const UTF8 *FromPtr = (UTF8 *)String.data();
+ UTF16 *ToPtr = &ToBuf[0];
+
+ ConversionResult Result = ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes,
+ &ToPtr, ToPtr + NumBytes,
+ strictConversion);
+ // Check for conversion failure.
+ if (Result != conversionOK)
+ Diag(Arg->getLocStart(),
+ diag::warn_cfstring_truncated) << Arg->getSourceRange();
+ }
return false;
}
@@ -798,7 +749,7 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
} else if (numElements != numResElements) {
QualType eltType = LHSType->getAs<VectorType>()->getElementType();
resType = Context.getVectorType(eltType, numResElements,
- VectorType::NotAltiVec);
+ VectorType::GenericVector);
}
}
@@ -929,31 +880,44 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
bool HasVAListArg,
unsigned format_idx, unsigned firstDataArg,
bool isPrintf) {
-
+ tryAgain:
if (E->isTypeDependent() || E->isValueDependent())
return false;
switch (E->getStmtClass()) {
+ case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass: {
- const ConditionalOperator *C = cast<ConditionalOperator>(E);
+ const AbstractConditionalOperator *C = cast<AbstractConditionalOperator>(E);
return SemaCheckStringLiteral(C->getTrueExpr(), TheCall, HasVAListArg,
format_idx, firstDataArg, isPrintf)
- && SemaCheckStringLiteral(C->getRHS(), TheCall, HasVAListArg,
+ && SemaCheckStringLiteral(C->getFalseExpr(), TheCall, HasVAListArg,
format_idx, firstDataArg, isPrintf);
}
+ case Stmt::IntegerLiteralClass:
+ // Technically -Wformat-nonliteral does not warn about this case.
+ // The behavior of printf and friends in this case is implementation
+ // dependent. Ideally if the format string cannot be null then
+ // it should have a 'nonnull' attribute in the function prototype.
+ return true;
+
case Stmt::ImplicitCastExprClass: {
- const ImplicitCastExpr *Expr = cast<ImplicitCastExpr>(E);
- return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
- format_idx, firstDataArg, isPrintf);
+ E = cast<ImplicitCastExpr>(E)->getSubExpr();
+ goto tryAgain;
}
case Stmt::ParenExprClass: {
- const ParenExpr *Expr = cast<ParenExpr>(E);
- return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
- format_idx, firstDataArg, isPrintf);
+ E = cast<ParenExpr>(E)->getSubExpr();
+ goto tryAgain;
}
+ case Stmt::OpaqueValueExprClass:
+ if (const Expr *src = cast<OpaqueValueExpr>(E)->getSourceExpr()) {
+ E = src;
+ goto tryAgain;
+ }
+ return false;
+
case Stmt::DeclRefExprClass: {
const DeclRefExpr *DR = cast<DeclRefExpr>(E);
@@ -1072,12 +1036,16 @@ Sema::CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
// of member functions is counted. However, it doesn't appear in our own
// lists, so decrement format_idx in that case.
if (isa<CXXMemberCallExpr>(TheCall)) {
- // Catch a format attribute mistakenly referring to the object argument.
- if (format_idx == 0)
- return;
- --format_idx;
- if(firstDataArg != 0)
- --firstDataArg;
+ const CXXMethodDecl *method_decl =
+ dyn_cast<CXXMethodDecl>(TheCall->getCalleeDecl());
+ if (method_decl && method_decl->isInstance()) {
+ // Catch a format attribute mistakenly referring to the object argument.
+ if (format_idx == 0)
+ return;
+ --format_idx;
+ if(firstDataArg != 0)
+ --firstDataArg;
+ }
}
// CHECK: printf/scanf-like function is called with no format string.
@@ -1531,6 +1499,8 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
}
// Check each flag does not conflict with any other component.
+ if (!FS.hasValidThousandsGroupingPrefix())
+ HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
if (!FS.hasValidLeadingZeros())
HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
if (!FS.hasValidPlusPrefix())
@@ -1585,9 +1555,12 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
// or 'short' to an 'int'. This is done because printf is a varargs
// function.
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex))
- if (ICE->getType() == S.Context.IntTy)
- if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType()))
+ if (ICE->getType() == S.Context.IntTy) {
+ // All further checking is done on the subexpression.
+ Ex = ICE->getSubExpr();
+ if (ATR.matchesType(S.Context, Ex->getType()))
return true;
+ }
// We may be able to offer a FixItHint if it is a supported type.
PrintfSpecifier fixedFS = FS;
@@ -1794,8 +1767,8 @@ void Sema::CheckFormatString(const StringLiteral *FExpr,
//===--- CHECK: Return Address of Stack Variable --------------------------===//
-static DeclRefExpr* EvalVal(Expr *E);
-static DeclRefExpr* EvalAddr(Expr* E);
+static Expr *EvalVal(Expr *E, llvm::SmallVectorImpl<DeclRefExpr *> &refVars);
+static Expr *EvalAddr(Expr* E, llvm::SmallVectorImpl<DeclRefExpr *> &refVars);
/// CheckReturnStackAddr - Check if a return statement returns the address
/// of a stack variable.
@@ -1803,45 +1776,79 @@ 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.
- RetValExp = RetValExp->IgnoreParenCasts();
+ Expr *stackE = 0;
+ llvm::SmallVector<DeclRefExpr *, 8> refVars;
- if (BlockExpr *C = dyn_cast<BlockExpr>(RetValExp))
- if (C->hasBlockDeclRefExprs())
- Diag(C->getLocStart(), diag::err_ret_local_block)
- << C->getSourceRange();
+ // Perform checking for returned stack addresses, local blocks,
+ // label addresses or references to temporaries.
+ if (lhsType->isPointerType() || lhsType->isBlockPointerType()) {
+ stackE = EvalAddr(RetValExp, refVars);
+ } else if (lhsType->isReferenceType()) {
+ stackE = EvalVal(RetValExp, refVars);
+ }
- if (AddrLabelExpr *ALE = dyn_cast<AddrLabelExpr>(RetValExp))
- Diag(ALE->getLocStart(), diag::warn_ret_addr_label)
- << ALE->getSourceRange();
+ if (stackE == 0)
+ return; // Nothing suspicious was found.
- } 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)
- << DR->getDecl()->getDeclName() << RetValExp->getSourceRange();
+ SourceLocation diagLoc;
+ SourceRange diagRange;
+ if (refVars.empty()) {
+ diagLoc = stackE->getLocStart();
+ diagRange = stackE->getSourceRange();
+ } else {
+ // We followed through a reference variable. 'stackE' contains the
+ // problematic expression but we will warn at the return statement pointing
+ // at the reference variable. We will later display the "trail" of
+ // reference variables using notes.
+ diagLoc = refVars[0]->getLocStart();
+ diagRange = refVars[0]->getSourceRange();
+ }
+
+ if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(stackE)) { //address of local var.
+ Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_stack_ref
+ : diag::warn_ret_stack_addr)
+ << DR->getDecl()->getDeclName() << diagRange;
+ } else if (isa<BlockExpr>(stackE)) { // local block.
+ Diag(diagLoc, diag::err_ret_local_block) << diagRange;
+ } else if (isa<AddrLabelExpr>(stackE)) { // address of label.
+ Diag(diagLoc, diag::warn_ret_addr_label) << diagRange;
+ } else { // local temporary.
+ Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_local_temp_ref
+ : diag::warn_ret_local_temp_addr)
+ << diagRange;
+ }
+
+ // Display the "trail" of reference variables that we followed until we
+ // found the problematic expression using notes.
+ for (unsigned i = 0, e = refVars.size(); i != e; ++i) {
+ VarDecl *VD = cast<VarDecl>(refVars[i]->getDecl());
+ // If this var binds to another reference var, show the range of the next
+ // var, otherwise the var binds to the problematic expression, in which case
+ // show the range of the expression.
+ SourceRange range = (i < e-1) ? refVars[i+1]->getSourceRange()
+ : stackE->getSourceRange();
+ Diag(VD->getLocation(), diag::note_ref_var_local_bind)
+ << VD->getDeclName() << range;
}
}
/// EvalAddr - EvalAddr and EvalVal are mutually recursive functions that
/// check if the expression in a return statement evaluates to an address
-/// to a location on the stack. The recursion is used to traverse the
+/// to a location on the stack, a local block, an address of a label, or a
+/// reference to local temporary. The recursion is used to traverse the
/// AST of the return expression, with recursion backtracking when we
-/// encounter a subexpression that (1) clearly does not lead to the address
-/// of a stack variable or (2) is something we cannot determine leads to
-/// the address of a stack variable based on such local checking.
+/// encounter a subexpression that (1) clearly does not lead to one of the
+/// above problematic expressions (2) is something we cannot determine leads to
+/// a problematic expression based on such local checking.
+///
+/// Both EvalAddr and EvalVal follow through reference variables to evaluate
+/// the expression that they point to. Such variables are added to the
+/// 'refVars' vector so that we know what the reference variable "trail" was.
///
/// 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
-/// the refers to a stack variable.
+/// At the base case of the recursion is a check for the above problematic
+/// expressions.
///
/// This implementation handles:
///
@@ -1851,7 +1858,10 @@ Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
/// * arbitrary interplay between "&" and "*" operators
/// * pointer arithmetic from an address of a stack variable
/// * taking the address of an array element where the array is on the stack
-static DeclRefExpr* EvalAddr(Expr *E) {
+static Expr *EvalAddr(Expr *E, llvm::SmallVectorImpl<DeclRefExpr *> &refVars) {
+ if (E->isTypeDependent())
+ return NULL;
+
// We should only be called for evaluating pointer expressions.
assert((E->getType()->isAnyPointerType() ||
E->getType()->isBlockPointerType() ||
@@ -1864,7 +1874,23 @@ static DeclRefExpr* EvalAddr(Expr *E) {
switch (E->getStmtClass()) {
case Stmt::ParenExprClass:
// Ignore parentheses.
- return EvalAddr(cast<ParenExpr>(E)->getSubExpr());
+ return EvalAddr(cast<ParenExpr>(E)->getSubExpr(), refVars);
+
+ case Stmt::DeclRefExprClass: {
+ DeclRefExpr *DR = cast<DeclRefExpr>(E);
+
+ if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl()))
+ // If this is a reference variable, follow through to the expression that
+ // it points to.
+ if (V->hasLocalStorage() &&
+ V->getType()->isReferenceType() && V->hasInit()) {
+ // Add the reference variable to the "trail".
+ refVars.push_back(DR);
+ return EvalAddr(V->getInit(), refVars);
+ }
+
+ return NULL;
+ }
case Stmt::UnaryOperatorClass: {
// The only unary operator that make sense to handle here
@@ -1872,7 +1898,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
UnaryOperator *U = cast<UnaryOperator>(E);
if (U->getOpcode() == UO_AddrOf)
- return EvalVal(U->getSubExpr());
+ return EvalVal(U->getSubExpr(), refVars);
else
return NULL;
}
@@ -1893,7 +1919,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
if (!Base->getType()->isPointerType()) Base = B->getRHS();
assert (Base->getType()->isPointerType());
- return EvalAddr(Base);
+ return EvalAddr(Base, refVars);
}
// For conditional operators we need to see if either the LHS or RHS are
@@ -1902,12 +1928,27 @@ static DeclRefExpr* EvalAddr(Expr *E) {
ConditionalOperator *C = cast<ConditionalOperator>(E);
// Handle the GNU extension for missing LHS.
- if (Expr *lhsExpr = C->getLHS())
- if (DeclRefExpr* LHS = EvalAddr(lhsExpr))
- return LHS;
+ if (Expr *lhsExpr = C->getLHS()) {
+ // In C++, we can have a throw-expression, which has 'void' type.
+ if (!lhsExpr->getType()->isVoidType())
+ if (Expr* LHS = EvalAddr(lhsExpr, refVars))
+ return LHS;
+ }
- return EvalAddr(C->getRHS());
+ // In C++, we can have a throw-expression, which has 'void' type.
+ if (C->getRHS()->getType()->isVoidType())
+ return NULL;
+
+ return EvalAddr(C->getRHS(), refVars);
}
+
+ case Stmt::BlockExprClass:
+ if (cast<BlockExpr>(E)->getBlockDecl()->hasCaptures())
+ return E; // local block.
+ return NULL;
+
+ case Stmt::AddrLabelExprClass:
+ return E; // address of label.
// For casts, we need to handle conversions from arrays to
// pointer values, and pointer-to-pointer conversions.
@@ -1920,9 +1961,9 @@ static DeclRefExpr* EvalAddr(Expr *E) {
if (SubExpr->getType()->isPointerType() ||
SubExpr->getType()->isBlockPointerType() ||
SubExpr->getType()->isObjCQualifiedIdType())
- return EvalAddr(SubExpr);
+ return EvalAddr(SubExpr, refVars);
else if (T->isArrayType())
- return EvalVal(SubExpr);
+ return EvalVal(SubExpr, refVars);
else
return 0;
}
@@ -1941,7 +1982,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
case Stmt::CXXReinterpretCastExprClass: {
Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr();
if (S->getType()->isPointerType() || S->getType()->isBlockPointerType())
- return EvalAddr(S);
+ return EvalAddr(S, refVars);
else
return NULL;
}
@@ -1955,7 +1996,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
/// EvalVal - This function is complements EvalAddr in the mutual recursion.
/// See the comments for EvalAddr for more details.
-static DeclRefExpr* EvalVal(Expr *E) {
+static Expr *EvalVal(Expr *E, llvm::SmallVectorImpl<DeclRefExpr *> &refVars) {
do {
// We should only be called for evaluating non-pointer expressions, or
// expressions with a pointer type that are not used as references but instead
@@ -1975,13 +2016,24 @@ do {
}
case Stmt::DeclRefExprClass: {
- // 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.
+ // When we hit a DeclRefExpr we are looking at code that refers to a
+ // variable's name. If it's not a reference variable 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()) {
+ if (!V->getType()->isReferenceType())
+ return DR;
+
+ // Reference variable, follow through to the expression that
+ // it points to.
+ if (V->hasInit()) {
+ // Add the reference variable to the "trail".
+ refVars.push_back(DR);
+ return EvalVal(V->getInit(), refVars);
+ }
+ }
return NULL;
}
@@ -1999,7 +2051,7 @@ do {
UnaryOperator *U = cast<UnaryOperator>(E);
if (U->getOpcode() == UO_Deref)
- return EvalAddr(U->getSubExpr());
+ return EvalAddr(U->getSubExpr(), refVars);
return NULL;
}
@@ -2008,20 +2060,20 @@ do {
// 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());
+ return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase(), refVars);
}
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.
+ // non-NULL Expr's. If one is non-NULL, we return it.
ConditionalOperator *C = cast<ConditionalOperator>(E);
// Handle the GNU extension for missing LHS.
if (Expr *lhsExpr = C->getLHS())
- if (DeclRefExpr *LHS = EvalVal(lhsExpr))
+ if (Expr *LHS = EvalVal(lhsExpr, refVars))
return LHS;
- return EvalVal(C->getRHS());
+ return EvalVal(C->getRHS(), refVars);
}
// Accesses to members are potential references to data on the stack.
@@ -2037,11 +2089,16 @@ do {
if (M->getMemberDecl()->getType()->isReferenceType())
return NULL;
- return EvalVal(M->getBase());
+ return EvalVal(M->getBase(), refVars);
}
- // Everything else: we simply don't reason about them.
default:
+ // Check that we don't return or take the address of a reference to a
+ // temporary. This is only useful in C++.
+ if (!E->isTypeDependent() && E->isRValue())
+ return E;
+
+ // Everything else: we simply don't reason about them.
return NULL;
}
} while (true);
@@ -2055,8 +2112,8 @@ do {
void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) {
bool EmitWarning = true;
- Expr* LeftExprSansParen = lex->IgnoreParens();
- Expr* RightExprSansParen = rex->IgnoreParens();
+ Expr* LeftExprSansParen = lex->IgnoreParenImpCasts();
+ Expr* RightExprSansParen = rex->IgnoreParenImpCasts();
// Special case: check for x == x (which is OK).
// Do not emit warnings for such cases.
@@ -2117,19 +2174,19 @@ struct IntRange {
: Width(Width), NonNegative(NonNegative)
{}
- // Returns the range of the bool type.
+ /// Returns the range of the bool type.
static IntRange forBoolType() {
return IntRange(1, true);
}
- // Returns the range of an integral type.
- static IntRange forType(ASTContext &C, QualType T) {
- return forCanonicalType(C, T->getCanonicalTypeInternal().getTypePtr());
+ /// Returns the range of an opaque value of the given integral type.
+ static IntRange forValueOfType(ASTContext &C, QualType T) {
+ return forValueOfCanonicalType(C,
+ T->getCanonicalTypeInternal().getTypePtr());
}
- // Returns the range of an integeral type based on its canonical
- // representation.
- static IntRange forCanonicalType(ASTContext &C, const Type *T) {
+ /// Returns the range of an opaque value of a canonical integral type.
+ static IntRange forValueOfCanonicalType(ASTContext &C, const Type *T) {
assert(T->isCanonicalUnqualified());
if (const VectorType *VT = dyn_cast<VectorType>(T))
@@ -2137,8 +2194,12 @@ struct IntRange {
if (const ComplexType *CT = dyn_cast<ComplexType>(T))
T = CT->getElementType().getTypePtr();
+ // For enum types, use the known bit width of the enumerators.
if (const EnumType *ET = dyn_cast<EnumType>(T)) {
EnumDecl *Enum = ET->getDecl();
+ if (!Enum->isDefinition())
+ return IntRange(C.getIntWidth(QualType(T, 0)), false);
+
unsigned NumPositive = Enum->getNumPositiveBits();
unsigned NumNegative = Enum->getNumNegativeBits();
@@ -2151,13 +2212,34 @@ struct IntRange {
return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger());
}
- // Returns the supremum of two ranges: i.e. their conservative merge.
+ /// Returns the "target" range of a canonical integral type, i.e.
+ /// the range of values expressible in the type.
+ ///
+ /// This matches forValueOfCanonicalType except that enums have the
+ /// full range of their type, not the range of their enumerators.
+ static IntRange forTargetOfCanonicalType(ASTContext &C, const Type *T) {
+ assert(T->isCanonicalUnqualified());
+
+ if (const VectorType *VT = dyn_cast<VectorType>(T))
+ T = VT->getElementType().getTypePtr();
+ if (const ComplexType *CT = dyn_cast<ComplexType>(T))
+ T = CT->getElementType().getTypePtr();
+ if (const EnumType *ET = dyn_cast<EnumType>(T))
+ T = ET->getDecl()->getIntegerType().getTypePtr();
+
+ const BuiltinType *BT = cast<BuiltinType>(T);
+ assert(BT->isInteger());
+
+ return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger());
+ }
+
+ /// Returns the supremum of two ranges: i.e. their conservative merge.
static IntRange join(IntRange L, IntRange R) {
return IntRange(std::max(L.Width, R.Width),
L.NonNegative && R.NonNegative);
}
- // Returns the infinum of two ranges: i.e. their aggressive merge.
+ /// Returns the infinum of two ranges: i.e. their aggressive merge.
static IntRange meet(IntRange L, IntRange R) {
return IntRange(std::min(L.Width, R.Width),
L.NonNegative || R.NonNegative);
@@ -2169,7 +2251,7 @@ IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth) {
return IntRange(value.getMinSignedBits(), false);
if (value.getBitWidth() > MaxWidth)
- value.trunc(MaxWidth);
+ value = value.trunc(MaxWidth);
// isNonNegative() just checks the sign bit without considering
// signedness.
@@ -2224,11 +2306,9 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
if (CE->getCastKind() == CK_NoOp)
return GetExprRange(C, CE->getSubExpr(), MaxWidth);
- IntRange OutputTypeRange = IntRange::forType(C, CE->getType());
+ IntRange OutputTypeRange = IntRange::forValueOfType(C, CE->getType());
bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
- if (!isIntegerCast && CE->getCastKind() == CK_Unknown)
- isIntegerCast = CE->getSubExpr()->getType()->isIntegerType();
// Assume that non-integer casts can span the full range of the type.
if (!isIntegerCast)
@@ -2283,12 +2363,12 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
case BO_RemAssign:
case BO_AddAssign:
case BO_SubAssign:
- return IntRange::forType(C, E->getType());
+ return IntRange::forValueOfType(C, E->getType());
// Operations with opaque sources are black-listed.
case BO_PtrMemD:
case BO_PtrMemI:
- return IntRange::forType(C, E->getType());
+ return IntRange::forValueOfType(C, E->getType());
// Bitwise-and uses the *infinum* of the two source ranges.
case BO_And:
@@ -2303,14 +2383,14 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
if (IntegerLiteral *I
= dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
if (I->getValue() == 1) {
- IntRange R = IntRange::forType(C, E->getType());
+ IntRange R = IntRange::forValueOfType(C, E->getType());
return IntRange(R.Width, /*NonNegative*/ true);
}
}
// fallthrough
case BO_ShlAssign:
- return IntRange::forType(C, E->getType());
+ return IntRange::forValueOfType(C, E->getType());
// Right shift by a constant can narrow its left argument.
case BO_Shr:
@@ -2339,7 +2419,7 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
// Black-list pointer subtractions.
case BO_Sub:
if (BO->getLHS()->getType()->isPointerType())
- return IntRange::forType(C, E->getType());
+ return IntRange::forValueOfType(C, E->getType());
// fallthrough
default:
@@ -2362,7 +2442,7 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
// Operations with opaque sources are black-listed.
case UO_Deref:
case UO_AddrOf: // should be impossible
- return IntRange::forType(C, E->getType());
+ return IntRange::forValueOfType(C, E->getType());
default:
return GetExprRange(C, UO->getSubExpr(), MaxWidth);
@@ -2370,7 +2450,7 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
}
if (dyn_cast<OffsetOfExpr>(E)) {
- IntRange::forType(C, E->getType());
+ IntRange::forValueOfType(C, E->getType());
}
FieldDecl *BitField = E->getBitField();
@@ -2381,7 +2461,7 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
return IntRange(BitWidth, BitField->getType()->isUnsignedIntegerType());
}
- return IntRange::forType(C, E->getType());
+ return IntRange::forValueOfType(C, E->getType());
}
IntRange GetExprRange(ASTContext &C, Expr *E) {
@@ -2426,30 +2506,55 @@ bool IsSameFloatAfterCast(const APValue &value,
IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt));
}
-void AnalyzeImplicitConversions(Sema &S, Expr *E);
+void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC);
+
+static bool IsZero(Sema &S, Expr *E) {
+ // Suppress cases where we are comparing against an enum constant.
+ if (const DeclRefExpr *DR =
+ dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
+ if (isa<EnumConstantDecl>(DR->getDecl()))
+ return false;
+
+ // Suppress cases where the '0' value is expanded from a macro.
+ if (E->getLocStart().isMacroID())
+ return false;
-bool IsZero(Sema &S, Expr *E) {
llvm::APSInt Value;
return E->isIntegerConstantExpr(Value, S.Context) && Value == 0;
}
+static bool HasEnumType(Expr *E) {
+ // Strip off implicit integral promotions.
+ while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ if (ICE->getCastKind() != CK_IntegralCast &&
+ ICE->getCastKind() != CK_NoOp)
+ break;
+ E = ICE->getSubExpr();
+ }
+
+ return E->getType()->isEnumeralType();
+}
+
void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
BinaryOperatorKind op = E->getOpcode();
+ if (E->isValueDependent())
+ return;
+
if (op == BO_LT && IsZero(S, E->getRHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
- << "< 0" << "false"
+ << "< 0" << "false" << HasEnumType(E->getLHS())
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (op == BO_GE && IsZero(S, E->getRHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
- << ">= 0" << "true"
+ << ">= 0" << "true" << HasEnumType(E->getLHS())
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (op == BO_GT && IsZero(S, E->getLHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
- << "0 >" << "false"
+ << "0 >" << "false" << HasEnumType(E->getRHS())
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (op == BO_LE && IsZero(S, E->getLHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
- << "0 <=" << "true"
+ << "0 <=" << "true" << HasEnumType(E->getRHS())
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
}
}
@@ -2457,8 +2562,8 @@ void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
/// Analyze the operands of the given comparison. Implements the
/// fallback case from AnalyzeComparison.
void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) {
- AnalyzeImplicitConversions(S, E->getLHS());
- AnalyzeImplicitConversions(S, E->getRHS());
+ AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
+ AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
}
/// \brief Implements -Wsign-compare.
@@ -2476,7 +2581,11 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
// We don't do anything special if this isn't an unsigned integral
// comparison: we're only interested in integral comparisons, and
// signed comparisons only happen in cases we don't care to warn about.
- if (!T->hasUnsignedIntegerRepresentation())
+ //
+ // We also don't care about value-dependent expressions or expressions
+ // whose result is a constant.
+ if (!T->hasUnsignedIntegerRepresentation()
+ || E->isValueDependent() || E->isIntegerConstantExpr(S.Context))
return AnalyzeImpConvsInComparison(S, E);
Expr *lex = E->getLHS()->IgnoreParenImpCasts();
@@ -2503,8 +2612,8 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
// Go ahead and analyze implicit conversions in the operands. Note
// that we skip the implicit conversions on both sides.
- AnalyzeImplicitConversions(S, lex);
- AnalyzeImplicitConversions(S, rex);
+ AnalyzeImplicitConversions(S, lex, E->getOperatorLoc());
+ AnalyzeImplicitConversions(S, rex, E->getOperatorLoc());
// If the signed range is non-negative, -Wsign-compare won't fire,
// but we should still check for comparisons which are always true
@@ -2533,13 +2642,103 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
<< lex->getSourceRange() << rex->getSourceRange();
}
+/// Analyzes an attempt to assign the given value to a bitfield.
+///
+/// Returns true if there was something fishy about the attempt.
+bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
+ SourceLocation InitLoc) {
+ assert(Bitfield->isBitField());
+ if (Bitfield->isInvalidDecl())
+ return false;
+
+ // White-list bool bitfields.
+ if (Bitfield->getType()->isBooleanType())
+ return false;
+
+ // Ignore value- or type-dependent expressions.
+ if (Bitfield->getBitWidth()->isValueDependent() ||
+ Bitfield->getBitWidth()->isTypeDependent() ||
+ Init->isValueDependent() ||
+ Init->isTypeDependent())
+ return false;
+
+ Expr *OriginalInit = Init->IgnoreParenImpCasts();
+
+ llvm::APSInt Width(32);
+ Expr::EvalResult InitValue;
+ if (!Bitfield->getBitWidth()->isIntegerConstantExpr(Width, S.Context) ||
+ !OriginalInit->Evaluate(InitValue, S.Context) ||
+ !InitValue.Val.isInt())
+ return false;
+
+ const llvm::APSInt &Value = InitValue.Val.getInt();
+ unsigned OriginalWidth = Value.getBitWidth();
+ unsigned FieldWidth = Width.getZExtValue();
+
+ if (OriginalWidth <= FieldWidth)
+ return false;
+
+ llvm::APSInt TruncatedValue = Value.trunc(FieldWidth);
+
+ // It's fairly common to write values into signed bitfields
+ // that, if sign-extended, would end up becoming a different
+ // value. We don't want to warn about that.
+ if (Value.isSigned() && Value.isNegative())
+ TruncatedValue = TruncatedValue.sext(OriginalWidth);
+ else
+ TruncatedValue = TruncatedValue.zext(OriginalWidth);
+
+ if (Value == TruncatedValue)
+ return false;
+
+ std::string PrettyValue = Value.toString(10);
+ std::string PrettyTrunc = TruncatedValue.toString(10);
+
+ S.Diag(InitLoc, diag::warn_impcast_bitfield_precision_constant)
+ << PrettyValue << PrettyTrunc << OriginalInit->getType()
+ << Init->getSourceRange();
+
+ return true;
+}
+
+/// Analyze the given simple or compound assignment for warning-worthy
+/// operations.
+void AnalyzeAssignment(Sema &S, BinaryOperator *E) {
+ // Just recurse on the LHS.
+ AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
+
+ // We want to recurse on the RHS as normal unless we're assigning to
+ // a bitfield.
+ if (FieldDecl *Bitfield = E->getLHS()->getBitField()) {
+ if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(),
+ E->getOperatorLoc())) {
+ // Recurse, ignoring any implicit conversions on the RHS.
+ return AnalyzeImplicitConversions(S, E->getRHS()->IgnoreParenImpCasts(),
+ E->getOperatorLoc());
+ }
+ }
+
+ AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
+}
+
/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
-void DiagnoseImpCast(Sema &S, Expr *E, QualType T, unsigned diag) {
- S.Diag(E->getExprLoc(), diag) << E->getType() << T << E->getSourceRange();
+void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext,
+ unsigned diag) {
+ S.Diag(E->getExprLoc(), diag)
+ << E->getType() << T << E->getSourceRange() << SourceRange(CContext);
+}
+
+std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) {
+ if (!Range.Width) return "0";
+
+ llvm::APSInt ValueInRange = Value;
+ ValueInRange.setIsSigned(!Range.NonNegative);
+ ValueInRange = ValueInRange.trunc(Range.Width);
+ return ValueInRange.toString(10);
}
void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
- bool *ICContext = 0) {
+ SourceLocation CC, bool *ICContext = 0) {
if (E->isTypeDependent() || E->isValueDependent()) return;
const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr();
@@ -2547,6 +2746,13 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
if (Source == Target) return;
if (Target->isDependentType()) return;
+ // If the conversion context location is invalid or instantiated
+ // from a system macro, don't complain.
+ if (CC.isInvalid() ||
+ (CC.isMacroID() && S.Context.getSourceManager().isInSystemHeader(
+ S.Context.getSourceManager().getSpellingLoc(CC))))
+ return;
+
// Never diagnose implicit casts to bool.
if (Target->isSpecificBuiltinType(BuiltinType::Bool))
return;
@@ -2554,7 +2760,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
// Strip vector types.
if (isa<VectorType>(Source)) {
if (!isa<VectorType>(Target))
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_vector_scalar);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_vector_scalar);
Source = cast<VectorType>(Source)->getElementType().getTypePtr();
Target = cast<VectorType>(Target)->getElementType().getTypePtr();
@@ -2563,7 +2769,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
// Strip complex types.
if (isa<ComplexType>(Source)) {
if (!isa<ComplexType>(Target))
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_complex_scalar);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_complex_scalar);
Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
Target = cast<ComplexType>(Target)->getElementType().getTypePtr();
@@ -2591,15 +2797,21 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
return;
}
- DiagnoseImpCast(S, E, T, diag::warn_impcast_float_precision);
+ DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision);
}
return;
}
// If the target is integral, always warn.
- if ((TargetBT && TargetBT->isInteger()))
- // TODO: don't warn for integer values?
- DiagnoseImpCast(S, E, T, diag::warn_impcast_float_integer);
+ if ((TargetBT && TargetBT->isInteger())) {
+ Expr *InnerE = E->IgnoreParenImpCasts();
+ if (FloatingLiteral *LiteralExpr = dyn_cast<FloatingLiteral>(InnerE)) {
+ DiagnoseImpCast(S, LiteralExpr, T, CC,
+ diag::warn_impcast_literal_float_to_integer);
+ } else {
+ DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_integer);
+ }
+ }
return;
}
@@ -2608,14 +2820,27 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
return;
IntRange SourceRange = GetExprRange(S.Context, E);
- IntRange TargetRange = IntRange::forCanonicalType(S.Context, Target);
+ IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target);
if (SourceRange.Width > TargetRange.Width) {
+ // If the source is a constant, use a default-on diagnostic.
+ // TODO: this should happen for bitfield stores, too.
+ llvm::APSInt Value(32);
+ if (E->isIntegerConstantExpr(Value, S.Context)) {
+ std::string PrettySourceValue = Value.toString(10);
+ std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);
+
+ S.Diag(E->getExprLoc(), diag::warn_impcast_integer_precision_constant)
+ << PrettySourceValue << PrettyTargetValue
+ << E->getType() << T << E->getSourceRange() << clang::SourceRange(CC);
+ return;
+ }
+
// People want to build with -Wshorten-64-to-32 and not -Wconversion
// and by god we'll let them.
if (SourceRange.Width == 64 && TargetRange.Width == 32)
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_64_32);
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_precision);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_64_32);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision);
}
if ((TargetRange.NonNegative && !SourceRange.NonNegative) ||
@@ -2633,7 +2858,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
*ICContext = true;
}
- return DiagnoseImpCast(S, E, T, DiagID);
+ return DiagnoseImpCast(S, E, T, CC, DiagID);
}
return;
@@ -2642,35 +2867,38 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T);
void CheckConditionalOperand(Sema &S, Expr *E, QualType T,
- bool &ICContext) {
+ SourceLocation CC, bool &ICContext) {
E = E->IgnoreParenImpCasts();
if (isa<ConditionalOperator>(E))
return CheckConditionalOperator(S, cast<ConditionalOperator>(E), T);
- AnalyzeImplicitConversions(S, E);
+ AnalyzeImplicitConversions(S, E, CC);
if (E->getType() != T)
- return CheckImplicitConversion(S, E, T, &ICContext);
+ return CheckImplicitConversion(S, E, T, CC, &ICContext);
return;
}
void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) {
- AnalyzeImplicitConversions(S, E->getCond());
+ SourceLocation CC = E->getQuestionLoc();
+
+ AnalyzeImplicitConversions(S, E->getCond(), CC);
bool Suspicious = false;
- CheckConditionalOperand(S, E->getTrueExpr(), T, Suspicious);
- CheckConditionalOperand(S, E->getFalseExpr(), T, Suspicious);
+ CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious);
+ CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious);
// If -Wconversion would have warned about either of the candidates
// for a signedness conversion to the context type...
if (!Suspicious) return;
// ...but it's currently ignored...
- if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional))
+ if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional,
+ CC))
return;
// ...and -Wsign-compare isn't...
- if (!S.Diags.getDiagnosticLevel(diag::warn_mixed_sign_conditional))
+ if (!S.Diags.getDiagnosticLevel(diag::warn_mixed_sign_conditional, CC))
return;
// ...then check whether it would have warned about either of the
@@ -2678,10 +2906,10 @@ void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) {
if (E->getType() != T) {
Suspicious = false;
CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(),
- E->getType(), &Suspicious);
+ E->getType(), CC, &Suspicious);
if (!Suspicious)
CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(),
- E->getType(), &Suspicious);
+ E->getType(), CC, &Suspicious);
if (!Suspicious)
return;
}
@@ -2697,7 +2925,7 @@ void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) {
/// AnalyzeImplicitConversions - Find and report any interesting
/// implicit conversions in the given expression. There are a couple
/// of competing diagnostics here, -Wconversion and -Wsign-compare.
-void AnalyzeImplicitConversions(Sema &S, Expr *OrigE) {
+void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) {
QualType T = OrigE->getType();
Expr *E = OrigE->IgnoreParenImpCasts();
@@ -2713,19 +2941,25 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE) {
// The non-canonical typecheck is just an optimization;
// CheckImplicitConversion will filter out dead implicit conversions.
if (E->getType() != T)
- CheckImplicitConversion(S, E, T);
+ CheckImplicitConversion(S, E, T, CC);
// Now continue drilling into this expression.
// Skip past explicit casts.
if (isa<ExplicitCastExpr>(E)) {
E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts();
- return AnalyzeImplicitConversions(S, E);
+ return AnalyzeImplicitConversions(S, E, CC);
}
- // Do a somewhat different check with comparison operators.
- if (isa<BinaryOperator>(E) && cast<BinaryOperator>(E)->isComparisonOp())
- return AnalyzeComparison(S, cast<BinaryOperator>(E));
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+ // Do a somewhat different check with comparison operators.
+ if (BO->isComparisonOp())
+ return AnalyzeComparison(S, BO);
+
+ // And with assignments and compound assignments.
+ if (BO->isAssignmentOp())
+ return AnalyzeAssignment(S, BO);
+ }
// These break the otherwise-useful invariant below. Fortunately,
// we don't really need to recurse into them, because any internal
@@ -2737,9 +2971,9 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE) {
if (isa<SizeOfAlignOfExpr>(E)) return;
// Now just recurse over the expression's children.
- for (Stmt::child_iterator I = E->child_begin(), IE = E->child_end();
- I != IE; ++I)
- AnalyzeImplicitConversions(S, cast<Expr>(*I));
+ CC = E->getExprLoc();
+ for (Stmt::child_range I = E->children(); I; ++I)
+ AnalyzeImplicitConversions(S, cast<Expr>(*I), CC);
}
} // end anonymous namespace
@@ -2747,7 +2981,11 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE) {
/// Diagnoses "dangerous" implicit conversions within the given
/// expression (which is a full expression). Implements -Wconversion
/// and -Wsign-compare.
-void Sema::CheckImplicitConversions(Expr *E) {
+///
+/// \param CC the "context" location of the implicit conversion, i.e.
+/// the most location of the syntactic entity requiring the implicit
+/// conversion
+void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) {
// Don't diagnose in unevaluated contexts.
if (ExprEvalContexts.back().Context == Sema::Unevaluated)
return;
@@ -2756,7 +2994,14 @@ void Sema::CheckImplicitConversions(Expr *E) {
if (E->isTypeDependent() || E->isValueDependent())
return;
- AnalyzeImplicitConversions(*this, E);
+ // This is not the right CC for (e.g.) a variable initialization.
+ AnalyzeImplicitConversions(*this, E, CC);
+}
+
+void Sema::CheckBitFieldInitialization(SourceLocation InitLoc,
+ FieldDecl *BitField,
+ Expr *Init) {
+ (void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc);
}
/// CheckParmsForFunctionDef - Check that the parameters of the given
@@ -2764,11 +3009,12 @@ void Sema::CheckImplicitConversions(Expr *E) {
/// takes care of any checks that cannot be performed on the
/// declaration itself, e.g., that the types of each of the function
/// parameters are complete.
-bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
+bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd,
+ bool CheckParameterNames) {
bool HasInvalidParm = false;
- for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
-
+ for (; P != PEnd; ++P) {
+ ParmVarDecl *Param = *P;
+
// C99 6.7.5.3p4: the parameters in a parameter type list in a
// function declarator that is part of a function definition of
// that function shall not have incomplete type.
@@ -2783,7 +3029,8 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
// C99 6.9.1p5: If the declarator includes a parameter type list, the
// declaration of each parameter shall include an identifier.
- if (Param->getIdentifier() == 0 &&
+ if (CheckParameterNames &&
+ Param->getIdentifier() == 0 &&
!Param->isImplicit() &&
!getLangOptions().CPlusPlus)
Diag(Param->getLocation(), diag::err_parameter_name_omitted);
@@ -2811,7 +3058,8 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
// This is actually a lot of work to potentially be doing on every
// cast; don't do it if we're ignoring -Wcast_align (as is the default).
- if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align)
+ if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align,
+ TRange.getBegin())
== Diagnostic::Ignored)
return;
@@ -2850,3 +3098,47 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
<< TRange << Op->getSourceRange();
}
+void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) {
+ const Expr *BaseExpr = E->getBase()->IgnoreParenImpCasts();
+ const ConstantArrayType *ArrayTy =
+ Context.getAsConstantArrayType(BaseExpr->getType());
+ if (!ArrayTy)
+ return;
+
+ const Expr *IndexExpr = E->getIdx();
+ if (IndexExpr->isValueDependent())
+ return;
+ llvm::APSInt index;
+ if (!IndexExpr->isIntegerConstantExpr(index, Context))
+ return;
+
+ if (!index.isNegative()) {
+ llvm::APInt size = ArrayTy->getSize();
+ if (!size.isStrictlyPositive())
+ return;
+ if (size.getBitWidth() > index.getBitWidth())
+ index = index.sext(size.getBitWidth());
+ else if (size.getBitWidth() < index.getBitWidth())
+ size = size.sext(index.getBitWidth());
+
+ if (index.slt(size))
+ return;
+
+ Diag(E->getBase()->getLocStart(), diag::warn_array_index_exceeds_bounds)
+ << index.toString(10, true) << size.toString(10, true)
+ << IndexExpr->getSourceRange();
+ } else {
+ Diag(E->getBase()->getLocStart(), diag::warn_array_index_precedes_bounds)
+ << index.toString(10, true) << IndexExpr->getSourceRange();
+ }
+
+ const NamedDecl *ND = NULL;
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
+ ND = dyn_cast<NamedDecl>(DRE->getDecl());
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr))
+ ND = dyn_cast<NamedDecl>(ME->getMemberDecl());
+ if (ND)
+ Diag(ND->getLocStart(), diag::note_array_index_out_of_bounds)
+ << ND->getDeclName();
+}
+