| // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s |
| // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s |
| |
| int some_func(int *); |
| |
| // CHECK: VarDecl {{.*}} invalid_call |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 123 |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int invalid_call = some_func(123); |
| void test_invalid_call(int s) { |
| // CHECK: CallExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:13> |
| // CHECK-NEXT: `-BinaryOperator {{.*}} |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} <col:28> 'int' 1 |
| some_func(undef1, undef2+1); |
| |
| // CHECK: BinaryOperator {{.*}} '<dependent type>' contains-errors '=' |
| // CHECK-NEXT: |-DeclRefExpr {{.*}} 's' |
| // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| s = some_func(undef1); |
| |
| // CHECK: VarDecl {{.*}} var 'int' |
| // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| int var = some_func(undef1); |
| } |
| |
| int ambig_func(double); |
| int ambig_func(float); |
| |
| // CHECK: VarDecl {{.*}} ambig_call |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'ambig_func' |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 123 |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int ambig_call = ambig_func(123); |
| |
| // CHECK: VarDecl {{.*}} unresolved_call1 |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'bar' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int unresolved_call1 = bar(); |
| |
| // CHECK: VarDecl {{.*}} unresolved_call2 |
| // CHECK-NEXT:`-CallExpr {{.*}} contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'bar' |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 'baz' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'qux' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int unresolved_call2 = bar(baz(), qux()); |
| |
| constexpr int a = 10; |
| |
| // CHECK: VarDecl {{.*}} postfix_inc |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int postfix_inc = a++; |
| |
| // CHECK: VarDecl {{.*}} prefix_inc |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int prefix_inc = ++a; |
| |
| // CHECK: VarDecl {{.*}} unary_address |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-ParenExpr {{.*}} |
| // CHECK-NEXT: `-BinaryOperator {{.*}} '+' |
| // CHECK-NEXT: |-ImplicitCastExpr |
| // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'a' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int unary_address = &(a + 1); |
| |
| // CHECK: VarDecl {{.*}} unary_bitinverse |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-ParenExpr {{.*}} |
| // CHECK-NEXT: `-BinaryOperator {{.*}} '+' |
| // CHECK-NEXT: |-ImplicitCastExpr |
| // CHECK-NEXT: | `-ImplicitCastExpr |
| // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'a' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int unary_bitinverse = ~(a + 0.0); |
| |
| // CHECK: VarDecl {{.*}} binary |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: |-DeclRefExpr {{.*}} 'a' |
| // CHECK-NEXT: `-CXXNullPtrLiteralExpr |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int binary = a + nullptr; |
| |
| // CHECK: VarDecl {{.*}} ternary |
| // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: |-DeclRefExpr {{.*}} 'a' |
| // CHECK-NEXT: |-CXXNullPtrLiteralExpr |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' |
| // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors |
| int ternary = a ? nullptr : a; |
| |
| // CHECK: FunctionDecl |
| // CHECK-NEXT:|-ParmVarDecl {{.*}} x |
| // CHECK-NEXT:`-CompoundStmt |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' |
| // CHECK-NEXT: `-CallExpr {{.*}} contains-errors |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' |
| struct Foo {} foo; |
| void test(int x) { |
| foo.abc; |
| foo->func(x); |
| } |
| |
| struct Foo2 { |
| double func(); |
| class ForwardClass; |
| ForwardClass createFwd(); |
| |
| int overload(); |
| int overload(int, int); |
| }; |
| void test2(Foo2 f) { |
| // CHECK: RecoveryExpr {{.*}} 'double' |
| // CHECK-NEXT: |-MemberExpr {{.*}} '<bound member function type>' |
| // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'f' |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 |
| f.func(1); |
| // CHECK: RecoveryExpr {{.*}} 'Foo2::ForwardClass' |
| // CHECK-NEXT: `-MemberExpr {{.*}} '<bound member function type>' .createFwd |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'f' |
| f.createFwd(); |
| // CHECK: RecoveryExpr {{.*}} 'int' contains-errors |
| // CHECK-NEXT: |-UnresolvedMemberExpr |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'Foo2' |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 |
| f.overload(1); |
| } |
| |
| // CHECK: |-AlignedAttr {{.*}} alignas |
| // CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT:| `-UnresolvedLookupExpr {{.*}} 'invalid' |
| struct alignas(invalid()) Aligned {}; |
| |
| auto f(); |
| int f(double); |
| // CHECK: VarDecl {{.*}} unknown_type_call 'int' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' |
| int unknown_type_call = f(0, 0); |
| |
| void InvalidInitalizer(int x) { |
| struct Bar { Bar(); }; |
| // CHECK: `-VarDecl {{.*}} a1 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 |
| Bar a1(1); |
| // CHECK: `-VarDecl {{.*}} a2 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' |
| Bar a2(x); |
| // CHECK: `-VarDecl {{.*}} a3 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-InitListExpr |
| // CHECK-NEDT: `-DeclRefExpr {{.*}} 'x' |
| Bar a3{x}; |
| // CHECK: `-VarDecl {{.*}} a4 'Bar' |
| // CHECK-NEXT: `-ParenListExpr {{.*}} 'NULL TYPE' contains-errors |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' |
| Bar a4(invalid()); |
| // CHECK: `-VarDecl {{.*}} a5 'Bar' |
| // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' |
| Bar a5{invalid()}; |
| |
| // CHECK: `-VarDecl {{.*}} b1 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 |
| Bar b1 = 1; |
| // CHECK: `-VarDecl {{.*}} b2 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-InitListExpr |
| Bar b2 = {1}; |
| // CHECK: `-VarDecl {{.*}} b3 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} 'Bar' contains-errors |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' |
| Bar b3 = Bar(x); |
| // CHECK: `-VarDecl {{.*}} b4 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} 'Bar' contains-errors |
| // CHECK-NEXT: `-InitListExpr {{.*}} 'void' |
| // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' |
| Bar b4 = Bar{x}; |
| // CHECK: `-VarDecl {{.*}} b5 'Bar' |
| // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' |
| Bar b5 = Bar(invalid()); |
| // CHECK: `-VarDecl {{.*}} b6 'Bar' |
| // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar' |
| // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' |
| Bar b6 = Bar{invalid()}; |
| |
| // CHECK: RecoveryExpr {{.*}} 'Bar' contains-errors |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 |
| Bar(1); |
| |
| // CHECK: `-VarDecl {{.*}} var1 |
| // CHECK-NEXT: `-BinaryOperator {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 |
| int var1 = undef + 1; |
| } |
| void InitializerForAuto() { |
| // CHECK: `-VarDecl {{.*}} invalid a 'auto' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' |
| auto a = invalid(); |
| |
| // CHECK: `-VarDecl {{.*}} invalid b 'auto' |
| // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' |
| auto b = some_func(invalid()); |
| |
| decltype(ned); |
| // very bad initailizer: there is an unresolved typo expr internally, we just |
| // drop it. |
| // CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto' |
| auto unresolved_typo = gned.*[] {}; |
| } |
| |
| // Verified that the generated call operator is invalid. |
| // CHECK: |-CXXMethodDecl {{.*}} invalid operator() 'auto () const -> auto' |
| using Escape = decltype([] { return undef(); }()); |
| |
| // CHECK: VarDecl {{.*}} NoCrashOnInvalidInitList |
| // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue |
| // CHECK-NEXT: `-InitListExpr |
| // CHECK-NEXT: `-DesignatedInitExpr {{.*}} 'void' |
| // CHECK-NEXT: `-CXXNullPtrLiteralExpr {{.*}} 'std::nullptr_t' |
| struct { |
| int& abc; |
| } NoCrashOnInvalidInitList = { |
| .abc = nullptr, |
| }; |
| |
| // Verify the value category of recovery expression. |
| int prvalue(int); |
| int &lvalue(int); |
| int &&xvalue(int); |
| void ValueCategory() { |
| // CHECK: RecoveryExpr {{.*}} 'int' contains-errors |
| prvalue(); // call to a function (nonreference return type) yields a prvalue (not print by default) |
| // CHECK: RecoveryExpr {{.*}} 'int' contains-errors lvalue |
| lvalue(); // call to a function (lvalue reference return type) yields an lvalue. |
| // CHECK: RecoveryExpr {{.*}} 'int' contains-errors xvalue |
| xvalue(); // call to a function (rvalue reference return type) yields an xvalue. |
| } |
| |
| void InvalidCondition() { |
| // CHECK: IfStmt {{.*}} |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:7, col:15> '<dependent type>' contains-errors |
| // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:7> |
| if (invalid()) {} |
| |
| // CHECK: WhileStmt {{.*}} |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:10, col:18> '<dependent type>' contains-errors |
| // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10> |
| while (invalid()) {} |
| |
| // CHECK: SwitchStmt {{.*}} |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10> |
| switch(invalid()) { |
| case 1: |
| break; |
| } |
| // FIXME: figure out why the type of ConditionalOperator is not int. |
| // CHECK: ConditionalOperator {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors |
| // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} |
| // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1 |
| // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2 |
| invalid() ? 1 : 2; |
| } |
| |
| void CtorInitializer() { |
| struct S{int m}; |
| class MemberInit { |
| int x, y, z; |
| S s; |
| MemberInit() : x(invalid), y(invalid, invalid), z(invalid()), s(1,2) {} |
| // CHECK: CXXConstructorDecl {{.*}} MemberInit 'void ()' |
| // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'x' 'int' |
| // CHECK-NEXT: | `-ParenListExpr |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type>' |
| // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'y' 'int' |
| // CHECK-NEXT: | `-ParenListExpr |
| // CHECK-NEXT: | |-RecoveryExpr {{.*}} '<dependent type>' |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type>' |
| // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'z' 'int' |
| // CHECK-NEXT: | `-ParenListExpr |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type>' |
| // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} '<overloaded function type>' |
| // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 's' 'S' |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' contains-errors |
| // CHECK-NEXT: | |-IntegerLiteral {{.*}} 1 |
| // CHECK-NEXT: | `-IntegerLiteral {{.*}} 2 |
| }; |
| class BaseInit : S { |
| BaseInit(float) : S("no match") {} |
| // CHECK: CXXConstructorDecl {{.*}} BaseInit 'void (float)' |
| // CHECK-NEXT: |-ParmVarDecl |
| // CHECK-NEXT: |-CXXCtorInitializer 'S' |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' |
| // CHECK-NEXT: | `-StringLiteral |
| |
| BaseInit(double) : S(invalid) {} |
| // CHECK: CXXConstructorDecl {{.*}} BaseInit 'void (double)' |
| // CHECK-NEXT: |-ParmVarDecl |
| // CHECK-NEXT: |-CXXCtorInitializer 'S' |
| // CHECK-NEXT: | `-ParenListExpr |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type>' |
| }; |
| class DelegatingInit { |
| DelegatingInit(float) : DelegatingInit("no match") {} |
| // CHECK: CXXConstructorDecl {{.*}} DelegatingInit 'void (float)' |
| // CHECK-NEXT: |-ParmVarDecl |
| // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit' |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'DelegatingInit' |
| // CHECK-NEXT: | `-StringLiteral |
| |
| DelegatingInit(double) : DelegatingInit(invalid) {} |
| // CHECK: CXXConstructorDecl {{.*}} DelegatingInit 'void (double)' |
| // CHECK-NEXT: |-ParmVarDecl |
| // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit' |
| // CHECK-NEXT: | `-ParenListExpr |
| // CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type>' |
| }; |
| } |