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