fix some problems handling stmtexprs with labels (PR2374), and 
improve 'expression unused' diagnostics for stmtexprs.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54098 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 9b4de2b..d31bde2 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 25a86fa..bb5ed50 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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);
 }