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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to