Hi,

Please review the attached patch.

In Sema::BuildCXXFunctionalCastExpr, if the class has a destructor, the 
Op.SrcExpr might be a CXXBindTemporaryExpr which we need to unwrap.

In the testcase, the first new CHECK worked (because A does not have a 
destructor),  but the second CHECK failed (did not include the last 
parenthese) because D has a destructor.

I used dyn_cast_or_null just to be safe, becasue i don't know if it is 
possible for the BindExpr->getSubExpr() to be null.

Thanks
-- 
Olivier
>From 919a61662f483404b37859f795048bc864c0c7ac Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoff...@woboq.com>
Date: Fri, 28 Aug 2015 17:32:55 +0200
Subject: [PATCH] Fix the perentheses location when the constructor is called
 on a class that has a destructor

---
 lib/Sema/SemaCast.cpp         |  7 +++++--
 test/SemaCXX/sourceranges.cpp | 15 ++++++++++++++-
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index dea9c22..db276c6 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -2483,8 +2483,11 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
   Op.CheckCXXCStyleCast(/*FunctionalStyle=*/true, /*ListInit=*/false);
   if (Op.SrcExpr.isInvalid())
     return ExprError();
-  
-  if (CXXConstructExpr *ConstructExpr = dyn_cast<CXXConstructExpr>(Op.SrcExpr.get()))
+
+  auto ConstructExpr = dyn_cast<CXXConstructExpr>(Op.SrcExpr.get());
+  if (auto BindExpr = dyn_cast<CXXBindTemporaryExpr>(Op.SrcExpr.get()))
+    ConstructExpr = dyn_cast_or_null<CXXConstructExpr>(BindExpr->getSubExpr());
+  if (ConstructExpr)
     ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc));
 
   return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp
index 9ba003a..8f2cfe5 100644
--- a/test/SemaCXX/sourceranges.cpp
+++ b/test/SemaCXX/sourceranges.cpp
@@ -7,7 +7,7 @@ class P {
 };
 
 namespace foo {
-class A { public: A() {} };
+class A { public: A(int = 0) {} };
 enum B {};
 typedef int C;
 }
@@ -37,3 +37,16 @@ void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
   // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
   p1->~P<int>();
 }
+
+struct D {
+  D(int);
+  ~D();
+};
+
+void construct() {
+  using namespace foo;
+  A a = A(12);
+  // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'class foo::A' 'void (int)'
+  D d = D(12);
+  // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'struct D' 'void (int)'
+}
-- 
2.5.0

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to