brunodf created this revision.
brunodf added a reviewer: jeroen.dobbelaere.
brunodf added a project: clang.
brunodf requested review of this revision.
Herald added a subscriber: cfe-commits.
The invocation of a unary or binary operator for type-dependent expressions is
represented as a CXXOperatorCallExpr. Upon template instantiation,
TreeTransform::RebuildCXXOperatorCallExpr checks for the case of an overloaded
operator, but not for a PseudoObject, and will directly create a UnaryOperator
or BinaryOperator.
By invoking BuildUnaryOp or BuildBinaryOp instead, we also cover the case of
PseudoObjects.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D111639
Files:
clang/lib/Sema/TreeTransform.h
clang/test/SemaCXX/PR51855.cpp
Index: clang/test/SemaCXX/PR51855.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/PR51855.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -fms-extensions -emit-llvm %s -o - | FileCheck %s
+
+struct F { };
+
+F operator*=(F& lhs, int rhs);
+
+F operator++(F& lhs);
+
+struct S {
+ short _m;
+ S(short _m): _m(_m) { }
+
+ void putM(short rhs) { _m = rhs; }
+ short getM() { return _m; }
+
+ __declspec(property(get=getM, put=putM)) short theData;
+};
+
+int test1a(int i) {
+ S tmp(i);
+ tmp.theData *= 2;
+ return tmp.theData;
+}
+
+// CHECK-LABEL: define {{.*}} i32 @_Z6test1ai(i32 %i)
+// CHECK: call void @_ZN1SC1Es
+// CHECK: call signext i16 @_ZN1S4getMEv
+// CHECK: call void @_ZN1S4putMEs
+// CHECK: call signext i16 @_ZN1S4getMEv
+
+
+template <typename T>
+int test1b(int i) {
+ T tmp(i);
+ tmp.theData *= 2;
+ return tmp.theData;
+}
+
+template int test1b<S>(int);
+
+// CHECK-LABEL: define {{.*}} i32 @_Z6test1bI1SEii(i32 %i)
+// CHECK: call void @_ZN1SC1Es
+// CHECK: call signext i16 @_ZN1S4getMEv
+// CHECK: call void @_ZN1S4putMEs
+// CHECK: call signext i16 @_ZN1S4getMEv
+
+int test2a(int i) {
+ S tmp(i);
+ ++tmp.theData;
+ return tmp.theData;
+}
+
+// CHECK-LABEL: define {{.*}} i32 @_Z6test2ai(i32 %i)
+// CHECK: call void @_ZN1SC1Es
+// CHECK: call signext i16 @_ZN1S4getMEv
+// CHECK: call void @_ZN1S4putMEs
+// CHECK: call signext i16 @_ZN1S4getMEv
+
+template <typename T>
+int test2b(int i) {
+ T tmp(i);
+ ++tmp.theData;
+ return tmp.theData;
+}
+
+template int test2b<S>(int);
+
+// CHECK-LABEL: define {{.*}} i32 @_Z6test2bI1SEii(i32 %i)
+// CHECK: call void @_ZN1SC1Es
+// CHECK: call signext i16 @_ZN1S4getMEv
+// CHECK: call void @_ZN1S4putMEs
+// CHECK: call signext i16 @_ZN1S4getMEv
+
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -14605,7 +14605,8 @@
UnaryOperatorKind Opc
= UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
- return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
+ // Invoke BuildUnaryOp to check for PseudoObject inc/dec
+ return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, First);
}
} else {
if (!First->getType()->isOverloadableType() &&
@@ -14613,8 +14614,9 @@
// Neither of the arguments is an overloadable type, so try to
// create a built-in binary operation.
BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+ // Invoke BuildBinOp to check for PseudoObject assignment
ExprResult Result
- = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
+ = SemaRef.BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, First, Second);
if (Result.isInvalid())
return ExprError();
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits