[cfe-commits] r54098 - in /cfe/trunk: lib/AST/Expr.cpp lib/Sema/SemaExpr.cpp test/Sema/stmt_exprs.c

Chris Lattner sabre at nondot.org
Sat Jul 26 12:51:01 PDT 2008


Author: lattner
Date: Sat Jul 26 14:51:01 2008
New Revision: 54098

URL: http://llvm.org/viewvc/llvm-project?rev=54098&view=rev
Log:
fix some problems handling stmtexprs with labels (PR2374), and 
improve 'expression unused' diagnostics for stmtexprs.

Modified:
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/stmt_exprs.c

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=54098&r1=54097&r2=54098&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Jul 26 14:51:01 2008
@@ -347,10 +347,18 @@
     return true;
   case ObjCMessageExprClass:
     return true;
-  case StmtExprClass:
-    // TODO: check the inside of the statement expression
-    return true;
-
+  case StmtExprClass: {
+    // Statement exprs don't logically have side effects themselves, but are
+    // sometimes used in macros in ways that give them a type that is unused.
+    // For example ({ blah; foo(); }) will end up with a type if foo has a type.
+    // however, if the result of the stmt expr is dead, we don't want to emit a
+    // warning.
+    const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
+    if (!CS->body_empty())
+      if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
+        return E->hasLocalSideEffect();
+    return false;
+  }
   case CastExprClass:
     // If this is a cast to void, check the operand.  Otherwise, the result of
     // the cast is unused.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=54098&r1=54097&r2=54098&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jul 26 14:51:01 2008
@@ -2334,9 +2334,15 @@
   // as the type of the stmtexpr.
   QualType Ty = Context.VoidTy;
   
-  if (!Compound->body_empty())
-    if (Expr *LastExpr = dyn_cast<Expr>(Compound->body_back()))
+  if (!Compound->body_empty()) {
+    Stmt *LastStmt = Compound->body_back();
+    // If LastStmt is a label, skip down through into the body.
+    while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt))
+      LastStmt = Label->getSubStmt();
+    
+    if (Expr *LastExpr = dyn_cast<Expr>(LastStmt))
       Ty = LastExpr->getType();
+  }
   
   return new StmtExpr(Compound, Ty, LPLoc, RPLoc);
 }

Modified: cfe/trunk/test/Sema/stmt_exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/stmt_exprs.c?rev=54098&r1=54097&r2=54098&view=diff

==============================================================================
--- cfe/trunk/test/Sema/stmt_exprs.c (original)
+++ cfe/trunk/test/Sema/stmt_exprs.c Sat Jul 26 14:51:01 2008
@@ -1,4 +1,4 @@
-// RUN: clang %s -fsyntax-only
+// RUN: clang %s -fsyntax-only -verify
 
 typedef unsigned __uint32_t;
 
@@ -10,3 +10,13 @@
 int test(int _x) {
  return (__byte_swap_int_var(_x));
 }
+
+// PR2374
+int test2() { return ({L:5;}); }
+int test3() { return ({ {5;} }); }         // expected-error {{incompatible type returning 'void', expected 'int'}}\
+                                           // expected-warning {{expression result unused}}
+int test4() { return ({ ({5;}); }); }
+int test5() { return ({L1: L2: L3: 5;}); }
+int test6() { return ({5;}); }
+void test7() { ({5;}); }                   // expected-warning {{expression result unused}}
+





More information about the cfe-commits mailing list