[cfe-commits] r117324 - in /cfe/trunk: clang.xcodeproj/project.pbxproj include/clang/AST/Stmt.h lib/Sema/SemaExpr.cpp test/CodeGenCXX/stmtexpr.cpp

Fariborz Jahanian fjahanian at apple.com
Mon Oct 25 16:27:27 PDT 2010


Author: fjahanian
Date: Mon Oct 25 18:27:26 2010
New Revision: 117324

URL: http://llvm.org/viewvc/llvm-project?rev=117324&view=rev
Log:
Patch for mis-compile of statement expressions with
non-trivial copy constructors. // rdar: //8540501.
A test will be added to llvm nightly tests.

Added:
    cfe/trunk/test/CodeGenCXX/stmtexpr.cpp
Modified:
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=117324&r1=117323&r2=117324&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Mon Oct 25 18:27:26 2010
@@ -2039,7 +2039,6 @@
 			isa = PBXProject;
 			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
 			compatibilityVersion = "Xcode 2.4";
-			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				English,

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=117324&r1=117323&r2=117324&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Mon Oct 25 18:27:26 2010
@@ -383,6 +383,9 @@
   body_iterator body_begin() { return Body; }
   body_iterator body_end() { return Body + NumStmts; }
   Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
+  
+  void setLastStmt(Stmt *S)
+  { assert(NumStmts && "setLastStmt"); Body[NumStmts-1] = S; }
 
   typedef Stmt* const * const_body_iterator;
   const_body_iterator body_begin() const { return Body; }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=117324&r1=117323&r2=117324&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Oct 25 18:27:26 2010
@@ -7067,21 +7067,43 @@
   // If there are sub stmts in the compound stmt, take the type of the last one
   // as the type of the stmtexpr.
   QualType Ty = Context.VoidTy;
-
+  bool StmtExprMayBindToTemp = false;
   if (!Compound->body_empty()) {
     Stmt *LastStmt = Compound->body_back();
+    LabelStmt *LastLabelStmt = 0;
     // If LastStmt is a label, skip down through into the body.
-    while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt))
+    while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt)) {
+      LastLabelStmt = Label;
       LastStmt = Label->getSubStmt();
-
-    if (Expr *LastExpr = dyn_cast<Expr>(LastStmt))
+    }
+    if (Expr *LastExpr = dyn_cast<Expr>(LastStmt)) {
       Ty = LastExpr->getType();
+      if (!Ty->isDependentType() && !LastExpr->isTypeDependent()) {
+        ExprResult Res = PerformCopyInitialization(
+                            InitializedEntity::InitializeResult(LPLoc, 
+                                                                Ty,
+                                                                false),
+                                                   SourceLocation(),
+                                                   Owned(LastExpr));
+        if (Res.isInvalid())
+          return ExprError();
+        if ((LastExpr = Res.takeAs<Expr>())) {
+          if (!LastLabelStmt)
+            Compound->setLastStmt(LastExpr);
+          else
+            LastLabelStmt->setSubStmt(LastExpr);
+          StmtExprMayBindToTemp = true;
+        }
+      }
+    }
   }
 
   // FIXME: Check that expression type is complete/non-abstract; statement
   // expressions are not lvalues.
-
-  return Owned(new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc));
+  Expr *ResStmtExpr = new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc);
+  if (StmtExprMayBindToTemp)
+    return MaybeBindToTemporary(ResStmtExpr);
+  return Owned(ResStmtExpr);
 }
 
 ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,

Added: cfe/trunk/test/CodeGenCXX/stmtexpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/stmtexpr.cpp?rev=117324&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/stmtexpr.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/stmtexpr.cpp Mon Oct 25 18:27:26 2010
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -Wno-unused-value -emit-llvm -o - %s | FileCheck %s
+// rdar: //8540501
+extern "C" int printf(...);
+extern "C" void abort();
+
+struct A
+{
+  int i;
+  A (int j) : i(j) {printf("this = %p A(%d)\n", this, j);}
+  A (const A &j) : i(j.i) {printf("this = %p const A&(%d)\n", this, i);}
+  A& operator= (const A &j) { i = j.i; abort(); return *this; }
+  ~A() { printf("this = %p ~A(%d)\n", this, i); }
+};
+
+struct B
+{
+  int i;
+  B (const A& a) { i = a.i; }
+  B() {printf("this = %p B()\n", this);}
+  B (const B &j) : i(j.i) {printf("this = %p const B&(%d)\n", this, i);}
+  ~B() { printf("this = %p ~B(%d)\n", this, i); }
+};
+
+A foo(int j)
+{
+  return ({ j ? A(1) : A(0); });
+}
+
+
+void foo2()
+{
+  A b = ({ A a(1); A a1(2); A a2(3); a1; a2; a; });
+  if (b.i != 1)
+    abort(); 
+  A c = ({ A a(1); A a1(2); A a2(3); a1; a2; a; A a3(4); a2; a3; });
+  if (c.i != 4)
+    abort(); 
+}
+
+void foo3()
+{
+  const A &b = ({ A a(1); a; });
+  if (b.i != 1)
+    abort();
+}
+
+void foo4()
+{
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1AC1ERKS_
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: call void @_ZN1BC1ERK1A
+// CHECK: call void @_ZN1AD1Ev
+  const B &b = ({ A a(1); a; });
+  if (b.i != 1)
+    abort();
+}
+
+int main()
+{
+  foo2();
+  foo3();
+  foo4();
+  return foo(1).i-1;
+}





More information about the cfe-commits mailing list