summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/ExprCXX.h5
-rw-r--r--clang/test/Misc/ast-dump-invalid.cpp20
-rw-r--r--clang/test/SemaCXX/return.cpp8
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'}}
+}
OpenPOWER on IntegriCloud