================
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 %s
+
+// Test that 'auto' cannot be combined with a type specifier in C++.
+void f() {
+  auto int x = 1;        // expected-error {{'auto' cannot be combined with a 
type specifier}}
----------------
zygoloid wrote:

> The current logic does: `if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) 
> {` and this fails with:
> 
> ```
> template <typename Ty>
> void g() {
>   auto Ty x;
> }
> ```
> 
> because the token we get from lookahead is `identifier` for `Ty`. We do not 
> know that `Ty` is a type unless we do the annotation dance. Are you 
> suggesting the better approach is to wait until `DeclSpec::Finish()` and 
> determine it's invalid then?

I think something like that could be reasonable.

But first off, single-token lookahead seems useless here. Sure, you can 
identify that in `auto int n:` there's a problem, but it doesn't help at all 
for eg `auto constexpr int n:` -- in general you would need infinite lookahead 
to determine whether `auto` is "meant to be" a type or a storage class. So a 
lookahead-based approach seems wrong.

In terms of the right thing to do, one option would be to treat `auto` as 
neither a type specifier nor a storage class specifier until `Finish`. But 
given that we're not converting the type specifier to a storage class any more, 
I'd say we can set the auto type directly in the language modes where auto is a 
type, and only delay until `Finish` in the cases where it's a storage class.

https://github.com/llvm/llvm-project/pull/166004
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to