diff options
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 5 | ||||
-rw-r--r-- | clang/test/Misc/ast-dump-invalid.cpp | 20 | ||||
-rw-r--r-- | clang/test/SemaCXX/return.cpp | 8 |
3 files changed, 31 insertions, 2 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 040fbe7f925..aa33b61d7ce 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2915,8 +2915,9 @@ public: SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY { - assert(RParenLoc.isValid() || NumArgs == 1); - return RParenLoc.isValid() ? RParenLoc : getArg(0)->getLocEnd(); + if (!RParenLoc.isValid() && NumArgs > 0) + return getArg(NumArgs - 1)->getLocEnd(); + return RParenLoc; } static bool classof(const Stmt *T) { diff --git a/clang/test/Misc/ast-dump-invalid.cpp b/clang/test/Misc/ast-dump-invalid.cpp new file mode 100644 index 00000000000..3b97cc65409 --- /dev/null +++ b/clang/test/Misc/ast-dump-invalid.cpp @@ -0,0 +1,20 @@ +// RUN: not %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s + +namespace TestInvalidRParenOnCXXUnresolvedConstructExpr { +template <class T> +void f(T i, T j) { + return T (i, j; +} +} + +// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidRParenOnCXXUnresolvedConstructExpr +// CHECK-NEXT: `-FunctionTemplateDecl +// CHECK-NEXT: |-TemplateTypeParmDecl +// CHECK-NEXT: `-FunctionDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-ReturnStmt +// CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} <col:10, col:16> 'T' +// CHECK-NEXT: |-DeclRefExpr {{.*}} <col:13> 'T' lvalue ParmVar {{.*}} 'i' 'T' +// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:16> 'T' lvalue ParmVar {{.*}} 'j' 'T' diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp index 98dbd51f580..8c1664516a7 100644 --- a/clang/test/SemaCXX/return.cpp +++ b/clang/test/SemaCXX/return.cpp @@ -112,3 +112,11 @@ namespace ctor_returns_void { ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}} }; } + +void cxx_unresolved_expr() { + // The use of an undeclared variable tricks clang into building a + // CXXUnresolvedConstructExpr, and the missing ')' gives it an invalid source + // location for its rparen. Check that emitting a diag on the range of the + // expr doesn't assert. + return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{void function 'cxx_unresolved_expr' should not return a value}} expected-error {{use of undeclared identifier 'undeclared'}} +} |