// RUN: %clang_cc1 -fsyntax-only -verify %s struct A { // #A }; struct B { struct C{}; // #B_C enum E{}; }; namespace NS { struct D{}; } enum E {}; // #E typedef int T; using U = int; // Basic sanity check on the original fuzzing generated syntax template void test_template(); // expected-error@-1{{cannot combine with previous 'type-name' declaration specifier}} // The bug we're looking at is the result of parsing repeated named type // specifiers. All the record types actually go through a single path, so // we don't repeat all of them. The first few are a basic sanity check of // each one anyway A struct B::C test01; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} A union B::C test02; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} // expected-error@-2 {{use of 'C' with tag type that does not match previous declaration}} // expected-note@#B_C {{previous use is here}} A class B::C test03; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} A struct NS::D test04; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} A struct ::A test05; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} T struct B::C test06; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} U struct B::C test07; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} // enums _do_ need separate testing as they have a different syntax, and so // take a different path through the parser E struct B::C test08; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} A enum ::A test09; // expected-error@-1 {{use of 'A' with tag type that does not match previous declaration}} // expected-note@#A {{previous use is here}} A enum ::E test10; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} E enum B::E test11; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} E enum ::E test12; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} T enum ::E test13; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} E struct ::E test14; // expected-error@-1 {{use of 'E' with tag type that does not match previous declaration}} // expected-note@#E {{previous use is here}} // These cases also _technically_ go wrong, but when the initial type specifier // is namespaced, we get the required info from the parser directly, which avoids // the reading from the corrupted scope B::C struct ::B test15; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} B::C struct B::C test16; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} B::C struct NS::D test17; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} using Test18 = A struct ::A; // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}}