r316836 - PR35039: Materialize temporary objects before wrapping them in an
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 28 11:59:51 PDT 2017
Author: rsmith
Date: Sat Oct 28 11:59:51 2017
New Revision: 316836
URL: http://llvm.org/viewvc/llvm-project?rev=316836&view=rev
Log:
PR35039: Materialize temporary objects before wrapping them in an
OpaqueValueExpr in a GNU binary conditional expression.
It's not meaningful for a non-materialized temporary object to be used as a
common subexpression of multiple expressions.
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=316836&r1=316835&r2=316836&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Oct 28 11:59:51 2017
@@ -7242,6 +7242,16 @@ ExprResult Sema::ActOnConditionalOp(Sour
commonExpr = commonRes.get();
}
+ // If the common expression is a class or array prvalue, materialize it
+ // so that we can safely refer to it multiple times.
+ if (commonExpr->isRValue() && (commonExpr->getType()->isRecordType() ||
+ commonExpr->getType()->isArrayType())) {
+ ExprResult MatExpr = TemporaryMaterializationConversion(commonExpr);
+ if (MatExpr.isInvalid())
+ return ExprError();
+ commonExpr = MatExpr.get();
+ }
+
opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(),
commonExpr->getType(),
commonExpr->getValueKind(),
Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=316836&r1=316835&r2=316836&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Sat Oct 28 11:59:51 2017
@@ -834,7 +834,8 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.2] ?: [B6.6]
+// CXX98: 1: [B7.2] ?: [B6.6]
+// CXX11: 1: [B7.3] ?: [B6.6]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
// CHECK: 4: [B4.3] (CXXConstructExpr, class A)
@@ -843,10 +844,13 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B3 B2
// CHECK: [B5]
-// CHECK: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 2: [B5.1]
-// CHECK: 3: [B5.2] (CXXConstructExpr, class A)
-// CHECK: 4: [B5.3] (BindTemporary)
+// CXX98: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A)
+// CXX98: 2: [B5.1]
+// CXX98: 3: [B5.2] (CXXConstructExpr, class A)
+// CXX98: 4: [B5.3] (BindTemporary)
+// CXX11: 1: [B7.3] (ImplicitCastExpr, NoOp, const class A)
+// CXX11: 2: [B5.1] (CXXConstructExpr, class A)
+// CXX11: 3: [B5.2] (BindTemporary)
// CHECK: Preds (1): B7
// CHECK: Succs (1): B4
// CHECK: [B6]
@@ -861,10 +865,15 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: [B7]
// CHECK: 1: A() (CXXConstructExpr, class A)
// CHECK: 2: [B7.1] (BindTemporary)
-// CHECK: 3: [B7.2].operator bool
-// CHECK: 4: [B7.2]
-// CHECK: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.5] ? ... : ...
+// CXX98: 3: [B7.2].operator bool
+// CXX98: 4: [B7.2]
+// CXX98: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX98: T: [B7.5] ? ... : ...
+// CXX11: 3: [B7.2]
+// CXX11: 4: [B7.3].operator bool
+// CXX11: 5: [B7.3]
+// CXX11: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11: T: [B7.6] ? ... : ...
// CHECK: Preds (1): B8
// CHECK: Succs (2): B5 B6
// CHECK: [B0 (EXIT)]
@@ -886,7 +895,8 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.4] ?: [B6.6]
+// CXX98: 1: [B7.4] ?: [B6.6]
+// CXX11: 1: [B7.5] ?: [B6.6]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
// CHECK: 4: [B7.2]([B4.3])
@@ -894,10 +904,13 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B3 B2
// CHECK: [B5]
-// CHECK: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 2: [B5.1]
-// CHECK: 3: [B5.2] (CXXConstructExpr, class A)
-// CHECK: 4: [B5.3] (BindTemporary)
+// CXX98: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A)
+// CXX98: 2: [B5.1]
+// CXX98: 3: [B5.2] (CXXConstructExpr, class A)
+// CXX98: 4: [B5.3] (BindTemporary)
+// CXX11: 1: [B7.5] (ImplicitCastExpr, NoOp, const class A)
+// CXX11: 2: [B5.1] (CXXConstructExpr, class A)
+// CXX11: 3: [B5.2] (BindTemporary)
// CHECK: Preds (1): B7
// CHECK: Succs (1): B4
// CHECK: [B6]
@@ -914,10 +927,15 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: 2: [B7.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
// CHECK: 3: A() (CXXConstructExpr, class A)
// CHECK: 4: [B7.3] (BindTemporary)
-// CHECK: 5: [B7.4].operator bool
-// CHECK: 6: [B7.4]
-// CHECK: 7: [B7.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.7] ? ... : ...
+// CXX98: 5: [B7.4].operator bool
+// CXX98: 6: [B7.4]
+// CXX98: 7: [B7.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX98: T: [B7.7] ? ... : ...
+// CXX11: 5: [B7.4]
+// CXX11: 6: [B7.5].operator bool
+// CXX11: 7: [B7.5]
+// CXX11: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B5 B6
// CHECK: [B8]
@@ -925,7 +943,8 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: Preds (1): B9
// CHECK: Succs (1): B7
// CHECK: [B9]
-// CHECK: 1: [B12.2] ?: [B11.6]
+// CXX98: 1: [B12.2] ?: [B11.6]
+// CXX11: 1: [B12.3] ?: [B11.6]
// CHECK: 2: [B9.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B9.2]
// CHECK: 4: const A &a = A() ?: A();
@@ -933,10 +952,13 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: Preds (2): B10 B11
// CHECK: Succs (2): B8 B7
// CHECK: [B10]
-// CHECK: 1: [B12.2] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 2: [B10.1]
-// CHECK: 3: [B10.2] (CXXConstructExpr, class A)
-// CHECK: 4: [B10.3] (BindTemporary)
+// CXX98: 1: [B12.2] (ImplicitCastExpr, NoOp, const class A)
+// CXX98: 2: [B10.1]
+// CXX98: 3: [B10.2] (CXXConstructExpr, class A)
+// CXX98: 4: [B10.3] (BindTemporary)
+// CXX11: 1: [B12.3] (ImplicitCastExpr, NoOp, const class A)
+// CXX11: 2: [B10.1] (CXXConstructExpr, class A)
+// CXX11: 3: [B10.2] (BindTemporary)
// CHECK: Preds (1): B12
// CHECK: Succs (1): B9
// CHECK: [B11]
@@ -951,10 +973,15 @@ int testConsistencyNestedNormalReturn(bo
// CHECK: [B12]
// CHECK: 1: A() (CXXConstructExpr, class A)
// CHECK: 2: [B12.1] (BindTemporary)
-// CHECK: 3: [B12.2].operator bool
-// CHECK: 4: [B12.2]
-// CHECK: 5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B12.5] ? ... : ...
+// CXX98: 3: [B12.2].operator bool
+// CXX98: 4: [B12.2]
+// CXX98: 5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX98: T: [B12.5] ? ... : ...
+// CXX11: 3: [B12.2]
+// CXX11: 4: [B12.3].operator bool
+// CXX11: 5: [B12.3]
+// CXX11: 6: [B12.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11: T: [B12.6] ? ... : ...
// CHECK: Preds (1): B13
// CHECK: Succs (2): B10 B11
// CHECK: [B0 (EXIT)]
Modified: cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp?rev=316836&r1=316835&r2=316836&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp Sat Oct 28 11:59:51 2017
@@ -6,6 +6,8 @@ struct A {
A(const A&);
~A();
+ operator bool();
+
int arr[10];
};
@@ -79,3 +81,27 @@ void i() {
// CHECK-LABEL: }
}
+
+// CHECK-LABEL: define {{.*}} @_Z1jv(
+void j() {
+ // CHECK: alloca %{{.*}}*
+ // CHECK: %[[OUTERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: %[[INNERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
+ // CHECK: call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
+ // CHECK: br i1
+ //
+ // CHECK: call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
+ A &&a = A(1) ?: A(2);
+
+ // CHECK: call void @_Z1iv()
+ i();
+
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
+}
More information about the cfe-commits
mailing list