]> granicus.if.org Git - clang/commitdiff
Remove an assert that's not true on invalid code.
authorNico Weber <nicolasweber@gmx.de>
Sun, 4 Jan 2015 20:32:12 +0000 (20:32 +0000)
committerNico Weber <nicolasweber@gmx.de>
Sun, 4 Jan 2015 20:32:12 +0000 (20:32 +0000)
r185773 added an assert that checked that a CXXUnresolvedConstructExpr either
has a valid rparen, or exactly one argument.  This doesn't have to be true for
invalid inputs.  Convert the assert to an if, and add a test for this case.

Found by SLi's afl bot.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225140 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
test/Misc/ast-dump-invalid.cpp [new file with mode: 0644]
test/SemaCXX/return.cpp

index 040fbe7f92515a1e351a0f822a7c65e6ca3e7f91..aa33b61d7ce52df67a4908f3e47bcfb723c60e05 100644 (file)
@@ -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/test/Misc/ast-dump-invalid.cpp b/test/Misc/ast-dump-invalid.cpp
new file mode 100644 (file)
index 0000000..3b97cc6
--- /dev/null
@@ -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'
index 98dbd51f58068419c3f76b334a36d2ee51d490ad..8c1664516a710e6f33278471ae3a8b5720e40fb2 100644 (file)
@@ -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'}}
+}