]> granicus.if.org Git - clang/commitdiff
Include the correct conversion context locations for condition expressions.
authorDavid Blaikie <dblaikie@gmail.com>
Wed, 16 May 2012 04:20:04 +0000 (04:20 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Wed, 16 May 2012 04:20:04 +0000 (04:20 +0000)
This improves the conversion diagnostics (by correctly pointing to the loop
construct for conversions that may've been caused by the contextual conversion
to bool caused by a condition expression) and also causes the NULL conversion
warnings to be correctly suppressed when crossing a macro boundary in such a
context. (previously, since the conversion context location was incorrect, the
suppression could not be performed)

Reported by Nico Weber as feedback to r156826.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156901 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Parse/ParseStmt.cpp
lib/Sema/SemaExprCXX.cpp
test/SemaCXX/conversion.cpp

index 7a24ca0effaf8ee2c4174f8e5e62201b52ff313f..98baeb0b8b4015e5084b1a4ea38c3f8c641235f1 100644 (file)
@@ -2402,7 +2402,10 @@ public:
   };
 
   FullExprArg MakeFullExpr(Expr *Arg) {
-    return FullExprArg(ActOnFinishFullExpr(Arg).release());
+    return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
+  }
+  FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
+    return FullExprArg(ActOnFinishFullExpr(Arg, CC).release());
   }
 
   StmtResult ActOnExprStmt(FullExprArg Expr);
@@ -3795,7 +3798,11 @@ public:
   Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt);
   ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr);
 
-  ExprResult ActOnFinishFullExpr(Expr *Expr);
+  ExprResult ActOnFinishFullExpr(Expr *Expr) {
+    return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
+                                          : SourceLocation());
+  }
+  ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC);
   StmtResult ActOnFinishFullStmt(Stmt *Stmt);
 
   // Marks SS invalid if it represents an incomplete type.
index 9796ea69bacd6cf2329d846dfb9526fb78b4d117..6652beaff49b4aa037ba18fbafc238babd3b0ed3 100644 (file)
@@ -948,7 +948,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
   if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
     return StmtError();
 
-  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get()));
+  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc));
 
   // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
@@ -1174,7 +1174,7 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
   if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))
     return StmtError();
 
-  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get()));
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));
 
   // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
@@ -1451,7 +1451,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
                                                  Second.get());
       }
       SecondPartIsInvalid = Second.isInvalid();
-      SecondPart = Actions.MakeFullExpr(Second.get());
+      SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc);
     }
 
     if (Tok.isNot(tok::semi)) {
index c0ba2d6cf8af73971655562eb119311909652eea..3400529c76ebc82cef14a9a1dc39941b23629cab 100644 (file)
@@ -5310,7 +5310,7 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) {
   return Owned(E);
 }
 
-ExprResult Sema::ActOnFinishFullExpr(Expr *FE) {
+ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC) {
   ExprResult FullExpr = Owned(FE);
 
   if (!FullExpr.get())
@@ -5336,7 +5336,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE) {
   if (FullExpr.isInvalid())
     return ExprError();
 
-  CheckImplicitConversions(FullExpr.get(), FullExpr.get()->getExprLoc());
+  CheckImplicitConversions(FullExpr.get(), CC);
   return MaybeCreateExprWithCleanups(FullExpr);
 }
 
index 60e440f234a894fee7efe91b2d2802c9f97811a3..a9efd8c14969cca1e9118ccf3d06506d36e63982 100644 (file)
@@ -81,6 +81,14 @@ void test3() {
   // and avoiding that helps us skip these cases:
 #define NULL_COND(cond) ((cond) ? &a : NULL)
   bool bl2 = NULL_COND(true); // don't warn on NULL conversion through the conditional operator across a macro boundary
+  if (NULL_COND(true))
+    ;
+  while (NULL_COND(true))
+    ;
+  for (; NULL_COND(true); )
+    ;
+  do ;
+  while(NULL_COND(true));
 }
 
 namespace test4 {