When dumping the following C++11 chunk of code
$ cat chunk.cc
struct A { A(int, int); };
A a_paren( A(0,0) );
A a_range( A{0,0} );
the CXXTemporaryObjectExpr generated by A{0,0}
is missing a proper end location
(the source location is correctly set for A(0,0)).
$ clang -cc1 -std=c++11 -ast-dump chunk.cc
[...]
`-VarDecl 0x5a963e0 <line:3:1, col:19> a_range 'struct A'
`-CXXConstructExpr 0x5a96570 <col:3, col:19> 'struct A' 'void (struct
A &&) noexcept' elidable
`-MaterializeTemporaryExpr 0x5a96550 <col:12, <invalid sloc>>
'struct A' xvalue
`-CXXTemporaryObjectExpr 0x5a964d8 <col:12, <invalid sloc>>
'struct A' 'void (int, int)'
|-IntegerLiteral 0x5a96448 <col:14> 'int' 0
`-IntegerLiteral 0x5a96468 <col:16> 'int' 0
Please find attached a patch (with testcase) fixing this issue.
OK to commit?
Enea.
Index: unittests/AST/SourceLocationTest.cpp
===================================================================
--- unittests/AST/SourceLocationTest.cpp (revision 189781)
+++ unittests/AST/SourceLocationTest.cpp (working copy)
@@ -211,6 +211,15 @@
functionalCastExpr(), Lang_CXX11));
}
+TEST(CXXTemporaryObjectExpr, SourceRange) {
+ RangeVerifier<CXXTemporaryObjectExpr> Verifier;
+ Verifier.expectRange(2, 6, 2, 12);
+ EXPECT_TRUE(Verifier.match(
+ "struct A { A(int, int); };\n"
+ "A a( A{0, 0} );",
+ temporaryObjectExpr(), Lang_CXX11));
+}
+
TEST(CXXUnresolvedConstructExpr, SourceRange) {
RangeVerifier<CXXUnresolvedConstructExpr> Verifier;
Verifier.expectRange(3, 10, 3, 12);
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp (revision 189781)
+++ lib/Sema/SemaInit.cpp (working copy)
@@ -5066,7 +5066,9 @@
MultiExprArg Args,
const InitializationSequence::Step& Step,
bool &ConstructorInitRequiresZeroInit,
- bool IsListInitialization) {
+ bool IsListInitialization,
+ SourceLocation LBraceLoc,
+ SourceLocation RBraceLoc) {
unsigned NumArgs = Args.size();
CXXConstructorDecl *Constructor
= cast<CXXConstructorDecl>(Step.Function.Function);
@@ -5119,7 +5121,9 @@
if (!TSInfo)
TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc);
SourceRange ParenRange;
- if (Kind.getKind() != InitializationKind::IK_DirectList)
+ if (Kind.getKind() == InitializationKind::IK_DirectList)
+ ParenRange = SourceRange(LBraceLoc, RBraceLoc);
+ else
ParenRange = Kind.getParenRange();
CurInit = S.Owned(
@@ -5913,7 +5917,9 @@
Entity,
Kind, Arg, *Step,
ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/ true);
+ /*IsListInitialization*/ true,
+ InitList->getLBraceLoc(),
+ InitList->getRBraceLoc());
break;
}
@@ -5947,7 +5953,9 @@
: Entity,
Kind, Args, *Step,
ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/ false);
+ /*IsListInitialization*/ false,
+ /*LBraceLoc*/ SourceLocation(),
+ /*RBraceLoc*/ SourceLocation());
break;
}
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h (revision 189781)
+++ include/clang/ASTMatchers/ASTMatchers.h (working copy)
@@ -1269,6 +1269,16 @@
Stmt,
CXXFunctionalCastExpr> functionalCastExpr;
+/// \brief Matches functional cast expressions having N != 1 arguments
+///
+/// Example: Matches Foo(bar, bar)
+/// \code
+/// Foo h = Foo(bar, bar);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ CXXTemporaryObjectExpr> temporaryObjectExpr;
+
/// \brief Matches \c QualTypes in the clang AST.
const internal::VariadicAllOfMatcher<QualType> qualType;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits