[Clang] Revert "Reject auto combined with type specifiers in C++ (#208552)" and follow-ups commits - #215320
Conversation
…lvm#210085)" This reverts commit de4b1f5.
…on (llvm#210347)" This reverts commit d592aa5.
This reverts commit 226acaf.
This reverts commit 72af746.
|
@llvm/pr-subscribers-clang Author: Tony Guillot (to268) ChangesThe initial fix for #164273 had several follow up commits to fix the initial implementation. This fix induces a lot of regressions and a refactoring of the area is required in order to fix the issue in a later release. This reverts the following commits (from oldest to latest): Patch is 38.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/215320.diff 15 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 51fe39f3733b1..72d1f0ecb92f1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2775,8 +2775,6 @@ def err_decltype_auto_invalid : Error<
"'decltype(auto)' not allowed here">;
def err_decltype_auto_cannot_be_combined : Error<
"'decltype(auto)' cannot be combined with other type specifiers">;
-def err_auto_type_specifier : Error<
- "'auto' cannot be combined with a type specifier">;
def err_decltype_auto_function_declarator_not_declaration : Error<
"'decltype(auto)' can only be used as a return type "
"in a function declaration">;
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 659bc06a257b5..e6dc6831d893f 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -363,10 +363,6 @@ class DeclSpec {
unsigned TypeSpecSat : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned ConstrainedAuto : 1;
- // Track conflicting type specifier when 'auto' is set (for Finish()
- // detection)
- LLVM_PREFERRED_TYPE(TST)
- unsigned ConflictingTypeSpecifier : 7;
// type-qualifiers
LLVM_PREFERRED_TYPE(TQ)
@@ -431,50 +427,10 @@ class DeclSpec {
SourceLocation FS_explicitCloseParenLoc;
SourceLocation FS_forceinlineLoc;
SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc;
- SourceLocation TQ_pipeLoc, ConflictingTypeSpecifierLoc;
+ SourceLocation TQ_pipeLoc;
WrittenBuiltinSpecs writtenBS;
void SaveWrittenBuiltinSpecs();
- void setConflictingTypeSpecifier(TST T, SourceLocation Loc) {
- // Store conflicting type specifier for Finish() to detect:
- // - If 'auto' is already set, store the conflicting type (e.g., "auto int")
- // - If 'auto' is being set after another type, store TST_auto
- // (e.g., "int auto").
- if (TypeSpecType == TST_auto) {
- ConflictingTypeSpecifier = T;
- ConflictingTypeSpecifierLoc = Loc;
- } else if (T == TST_auto) {
- ConflictingTypeSpecifier = TST_auto;
- ConflictingTypeSpecifierLoc = Loc;
- }
- }
- void setConflictingTypeSpecifier(TST T, SourceLocation Loc,
- SourceLocation NameLoc, ParsedType Rep) {
- setConflictingTypeSpecifier(T, Loc);
- if (TypeSpecType == TST_auto) {
- TypeRep = Rep;
- TSTNameLoc = NameLoc;
- TypeSpecOwned = false;
- }
- }
- void setConflictingTypeSpecifier(TST T, SourceLocation Loc, Expr *Rep) {
- setConflictingTypeSpecifier(T, Loc);
- if (TypeSpecType == TST_auto) {
- ExprRep = Rep;
- TSTNameLoc = Loc;
- TypeSpecOwned = false;
- }
- }
- void setConflictingTypeSpecifier(TST T, SourceLocation Loc,
- SourceLocation NameLoc, Decl *Rep,
- bool Owned) {
- setConflictingTypeSpecifier(T, Loc);
- if (TypeSpecType == TST_auto) {
- DeclRep = Rep;
- TSTNameLoc = NameLoc;
- TypeSpecOwned = Owned && Rep != nullptr;
- }
- }
ObjCDeclSpec *ObjCQualifiers;
@@ -518,15 +474,13 @@ class DeclSpec {
TypeSpecType(TST_unspecified), TypeAltiVecVector(false),
TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false),
TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
- ConflictingTypeSpecifier(TST_unspecified),
TypeQualifiers(TQ_unspecified),
OB_state(static_cast<unsigned>(OverflowBehaviorState::Unspecified)),
FS_inline_specified(false), FS_forceinline_specified(false),
FS_virtual_specified(false), FS_noreturn_specified(false),
FriendSpecifiedFirst(false), ConstexprSpecifier(static_cast<unsigned>(
ConstexprSpecKind::Unspecified)),
- Attrs(attrFactory), ConflictingTypeSpecifierLoc(), writtenBS(),
- ObjCQualifiers(nullptr) {}
+ Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {}
// storage-class-specifier
SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
@@ -566,9 +520,6 @@ class DeclSpec {
return static_cast<TypeSpecifierSign>(TypeSpecSign);
}
TST getTypeSpecType() const { return (TST)TypeSpecType; }
- bool hasConflictingTypeSpecifier() const {
- return ConflictingTypeSpecifier != TST_unspecified;
- }
bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
bool isTypeAltiVecBool() const { return TypeAltiVecBool; }
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 2aaeba9225c38..2bbc76fc7c4df 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3778,9 +3778,7 @@ void Parser::ParseDeclarationSpecifiers(
// This identifier can only be a typedef name if we haven't already seen
// a type-specifier. Without this check we misparse:
// typedef int X; struct Y { short X; }; as 'short int'.
- // However, if 'auto' is set, we need to check if this identifier is a
- // type name to detect conflicts (e.g., "auto MyInt").
- if (DS.hasTypeSpecifier() && DS.getTypeSpecType() != DeclSpec::TST_auto)
+ if (DS.hasTypeSpecifier())
goto DoneWithDeclSpec;
// If the token is an identifier named "__declspec" and Microsoft
@@ -3865,27 +3863,6 @@ void Parser::ParseDeclarationSpecifiers(
DS.isFriendSpecified()))
goto DoneWithDeclSpec;
- // If 'auto' is set and we're in a template parameter context, the
- // identifier is always the parameter name, not a type specifier, so skip
- // type name lookup to avoid false ambiguity errors.
- if (DS.getTypeSpecType() == DeclSpec::TST_auto &&
- DSContext == DeclSpecContext::DSC_template_param) {
- goto DoneWithDeclSpec;
- }
-
- // If 'auto' is set and the next token indicates this identifier is the
- // declarator-id, stop parsing declaration specifiers before doing type
- // lookup. Looking up the declarator-id can produce bogus ambiguity errors
- // when a variable name matches a type brought in by a using-directive.
- if (DS.getTypeSpecType() == DeclSpec::TST_auto) {
- Token Next = NextToken();
- if (Next.isOneOf(tok::equal, tok::l_paren, tok::l_square, tok::l_brace,
- tok::amp, tok::ampamp, tok::star, tok::coloncolon,
- tok::comma, tok::semi, tok::colon, tok::greater,
- tok::r_paren, tok::arrow))
- goto DoneWithDeclSpec;
- }
-
ParsedType TypeRep = Actions.getTypeName(
*Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), nullptr,
false, false, nullptr, false, false,
@@ -3893,16 +3870,11 @@ void Parser::ParseDeclarationSpecifiers(
// If this is not a typedef name, don't parse it as part of the declspec,
// it must be an implicit int or an error.
- // However, if 'auto' is already set, we can't have an implicit int.
if (!TypeRep) {
if (TryAnnotateTypeConstraint())
goto DoneWithDeclSpec;
if (Tok.isNot(tok::identifier))
continue;
- // If 'auto' is set, the identifier must be a type name or it's an
- // error. Don't try to parse it as implicit int.
- if (DS.getTypeSpecType() == DeclSpec::TST_auto)
- goto DoneWithDeclSpec;
ParsedAttributes Attrs(AttrFactory);
if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) {
if (!Attrs.empty()) {
@@ -4168,18 +4140,15 @@ void Parser::ParseDeclarationSpecifiers(
}
};
- if (!getLangOpts().CPlusPlus && MayBeTypeSpecifier()) {
+ if (MayBeTypeSpecifier()) {
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
PrevSpec, DiagID, Policy);
- } else {
- if (getLangOpts().CPlusPlus11 &&
- NextToken().isOneOf(tok::kw_class, tok::kw_struct,
- tok::kw___interface, tok::kw_union,
- tok::kw_enum))
- Diag(Loc, diag::ext_auto_storage_class);
+ if (!isInvalid && !getLangOpts().C23)
+ Diag(Tok, diag::ext_auto_storage_class)
+ << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
+ } else
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
DiagID, Policy);
- }
} else
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
PrevSpec, DiagID, Policy);
@@ -4734,8 +4703,7 @@ void Parser::ParseDeclarationSpecifiers(
DS.SetRangeEnd(ConsumedEnd.isValid() ? ConsumedEnd : Tok.getLocation());
// If the specifier wasn't legal, issue a diagnostic.
- // Skip diagnostic if 'auto' conflict will be handled in Finish()
- if (isInvalid && !DS.hasConflictingTypeSpecifier()) {
+ if (isInvalid) {
assert(PrevSpec && "Method did not return previous specifier!");
assert(DiagID);
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 1492bbf60a373..c13d5c8345604 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -431,7 +431,7 @@ void DeclSpec::forEachQualifier(
}
bool DeclSpec::hasTagDefinition() const {
- if (!TypeSpecOwned || !isDeclRep((TST)TypeSpecType))
+ if (!TypeSpecOwned)
return false;
return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition();
}
@@ -759,7 +759,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
if (TypeSpecType == TST_error)
return false;
if (TypeSpecType != TST_unspecified) {
- setConflictingTypeSpecifier(T, TagKwLoc, TagNameLoc, Rep);
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
return true;
@@ -791,7 +790,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
if (TypeSpecType == TST_error)
return false;
if (TypeSpecType != TST_unspecified) {
- setConflictingTypeSpecifier(T, Loc, Rep);
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
return true;
@@ -824,7 +822,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
if (TypeSpecType == TST_error)
return false;
if (TypeSpecType != TST_unspecified) {
- setConflictingTypeSpecifier(T, TagKwLoc, TagNameLoc, Rep, Owned);
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
return true;
@@ -855,7 +852,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
if (TypeSpecType == TST_error)
return false;
if (TypeSpecType != TST_unspecified) {
- setConflictingTypeSpecifier(T, Loc);
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
return true;
@@ -1216,181 +1212,6 @@ void DeclSpec::CheckTypeSpec(Sema &S, const PrintingPolicy &Policy) {
<< Hints[4] << Hints[5] << Hints[6] << Hints[7];
}
- // If 'auto' type specifier is combined with another type specifier, we need
- // to handle it based on the language:
- // - In C++11+: Emit error (cannot combine type specifiers)
- // - In C23: Convert 'auto' to storage class (valid)
- // - In OpenCL: Convert 'auto' to storage class, then OpenCL will reject it
- // Handle both cases:
- // - "auto int" (TypeSpecType == TST_auto, ConflictingTypeSpecifier ==
- // TST_int)
- // - "int auto" (TypeSpecType == TST_int, ConflictingTypeSpecifier ==
- // TST_auto)
- if (ConflictingTypeSpecifier != TST_unspecified) {
- // Special case: "auto auto" - duplicate 'auto', emit error
- if (TypeSpecType == TST_auto && ConflictingTypeSpecifier == TST_auto) {
- // Both are 'auto', emit "cannot combine with previous 'auto' declaration
- // specifier" error This matches GCC's "duplicate 'auto'" behavior Note:
- // We keep TypeSpecType = TST_auto (don't set to TST_error) so that later
- // checks in SemaType.cpp can emit "not allowed in function prototype" and
- // "not allowed in function return type" errors as needed.
- const char *PrevSpec = "auto";
- unsigned DiagID = diag::err_invalid_decl_spec_combination;
- S.Diag(ConflictingTypeSpecifierLoc, DiagID) << PrevSpec << PrevSpec;
- // Clear the conflict tracking but keep TypeSpecType = TST_auto
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- } else if ((S.getLangOpts().C23 && !S.getLangOpts().CPlusPlus) ||
- (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11)) {
- // In C23 or C++98, convert 'auto' to storage class specifier
- if (TypeSpecType == TST_auto) {
- // "auto int" case: Convert 'auto' to storage class specifier.
- // But typedef + any storage-class-specifier is unconditionally invalid
- // per [dcl.stc]p1, regardless of C++ version.
- if (StorageClassSpec == SCS_typedef) {
- S.Diag(TSTLoc, diag::err_invalid_decl_spec_combination)
- << "typedef" << FixItHint::CreateRemoval(TSTLoc);
- TypeSpecType = TST_error;
- } else {
- StorageClassSpec = SCS_auto;
- StorageClassSpecLoc = TSTLoc;
- TypeSpecType = ConflictingTypeSpecifier;
- TSTLoc = ConflictingTypeSpecifierLoc;
- }
- // Clear the conflict tracking
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- } else if (ConflictingTypeSpecifier == TST_auto) {
- // "int auto" case: Convert 'auto' to storage class specifier
- // In C23, if 'constexpr' is present, treat 'auto' as a type specifier
- // conflict with 'int' rather than converting it to storage class, so we
- // emit the "cannot combine with previous 'int' declaration specifier"
- // error and mark the type as error to prevent further processing.
- // Otherwise, convert 'auto' to storage class specifier (no type
- // conflict error).
- if (S.getLangOpts().C23 && !S.getLangOpts().CPlusPlus &&
- getConstexprSpecifier() != ConstexprSpecKind::Unspecified) {
- // constexpr int auto: treat as type specifier conflict
- const char *PrevSpec =
- getSpecifierName((TST)TypeSpecType, S.getPrintingPolicy());
- unsigned DiagID = diag::err_invalid_decl_spec_combination;
- S.Diag(ConflictingTypeSpecifierLoc, DiagID) << PrevSpec << "auto";
- TypeSpecType = TST_error;
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- return;
- }
- // int auto (without constexpr): Convert 'auto' to storage class
- // specifier. But typedef + any storage-class-specifier is
- // unconditionally invalid per [dcl.stc]p1.
- if (StorageClassSpec == SCS_typedef) {
- S.Diag(ConflictingTypeSpecifierLoc,
- diag::err_invalid_decl_spec_combination)
- << "typedef"
- << FixItHint::CreateRemoval(ConflictingTypeSpecifierLoc);
- TypeSpecType = TST_error;
- } else {
- StorageClassSpec = SCS_auto;
- StorageClassSpecLoc = ConflictingTypeSpecifierLoc;
- // TypeSpecType already has the correct type (e.g., TST_int)
- }
- // Clear the conflict tracking
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- }
- } else if (S.getLangOpts().OpenCL) {
- // For OpenCL (C or C++), convert 'auto' to storage class specifier first
- // (OpenCL will then reject it via SetStorageClassSpec checks)
- // This must come before the C++11+ check to handle OpenCL C++
- if (TypeSpecType == TST_auto) {
- // "auto int" case: Convert 'auto' to storage class specifier
- // Use SetStorageClassSpec to trigger OpenCL-specific error checking
- const char *PrevSpec = nullptr;
- unsigned DiagID = 0;
- if (SetStorageClassSpec(
- S, SCS_auto, TSTLoc, PrevSpec, DiagID,
- S.getPrintingPolicy())) { // OpenCL rejected it, emit the error
- // with version string
- if (S.getLangOpts().OpenCL && S.getLangOpts().CPlusPlus) {
- S.Diag(TSTLoc, DiagID)
- << S.getLangOpts().getOpenCLVersionString() << PrevSpec << 1;
- } else {
- S.Diag(TSTLoc, DiagID) << PrevSpec;
- }
- TypeSpecType = TST_error;
- } else {
- StorageClassSpec = SCS_auto;
- StorageClassSpecLoc = TSTLoc;
- TypeSpecType = ConflictingTypeSpecifier;
- TSTLoc = ConflictingTypeSpecifierLoc;
- }
- // Clear the conflict tracking
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- } else if (ConflictingTypeSpecifier == TST_auto) {
- // "int auto" case: Convert 'auto' to storage class specifier
- // Use SetStorageClassSpec to trigger OpenCL-specific error checking
- const char *PrevSpec = nullptr;
- unsigned DiagID = 0;
- if (SetStorageClassSpec(S, SCS_auto, ConflictingTypeSpecifierLoc,
- PrevSpec, DiagID, S.getPrintingPolicy())) {
- // OpenCL rejected it, emit the error with version string
- if (S.getLangOpts().OpenCL && S.getLangOpts().CPlusPlus) {
- S.Diag(ConflictingTypeSpecifierLoc, DiagID)
- << S.getLangOpts().getOpenCLVersionString() << PrevSpec << 1;
- } else {
- S.Diag(ConflictingTypeSpecifierLoc, DiagID) << PrevSpec;
- }
- TypeSpecType = TST_error;
- } else {
- StorageClassSpec = SCS_auto;
- StorageClassSpecLoc = ConflictingTypeSpecifierLoc;
- }
- // Clear the conflict tracking
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- }
- } else if (S.getLangOpts().CPlusPlus && S.getLangOpts().CPlusPlus11 &&
- !S.getLangOpts().C23) {
- // In C++11+ (but not C23 or OpenCL), emit error (cannot combine type
- // specifiers)
- if (TypeSpecType == TST_auto) {
- // "auto int" case
- S.Diag(ConflictingTypeSpecifierLoc, diag::err_auto_type_specifier)
- << FixItHint::CreateRemoval(ConflictingTypeSpecifierLoc);
- } else if (ConflictingTypeSpecifier == TST_auto) {
- // "int auto" case
- S.Diag(ConflictingTypeSpecifierLoc, diag::err_auto_type_specifier)
- << FixItHint::CreateRemoval(ConflictingTypeSpecifierLoc);
- }
- // Mark as error to prevent further processing
- TypeSpecType = TST_error;
- TypeSpecOwned = false;
- } else if (!S.getLangOpts().CPlusPlus) {
- // For C, C23, etc., convert 'auto' to storage class specifier
- // (This is already handled above for C23, but keep for other C dialects)
- // In C, C23, OpenCL, etc., convert 'auto' to storage class specifier
- if (TypeSpecType == TST_auto) {
- // "auto int" case: Convert 'auto' to storage class specifier
- StorageClassSpec = SCS_auto;
- StorageClassSpecLoc = TSTLoc;
- TypeSpecType = ConflictingTypeSpecifier;
- TSTLoc = ConflictingTypeSpecifierLoc;
- // Clear the conflict tracking
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocation();
- } else if (ConflictingTypeSpecifier == TST_auto) {
- // "int auto" case: Convert 'auto' to storage class specifier
- StorageClassSpec = SCS_auto;
- StorageClassSpecLoc = ConflictingTypeSpecifierLoc;
- // TypeSpecType already has the correct type (e.g., TST_int)
- // Clear the conflict tracking
- ConflictingTypeSpecifier = TST_unspecified;
- ConflictingTypeSpecifierLoc = SourceLocat...
[truncated]
|
|
It should be noted that the llvm-project/clang/docs/ReleaseNotes.md Lines 119 to 120 in ea40e7f |
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions c,h,cpp -- clang/include/clang/Sema/DeclSpec.h clang/lib/Parse/ParseDecl.cpp clang/lib/Sema/DeclSpec.cpp clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp clang/test/CXX/dcl/dcl.fct/p17.cpp clang/test/CXX/drs/cwg3xx.cpp clang/test/Parser/c2x-auto.c clang/test/SemaCXX/auto-cxx0x.cpp clang/test/SemaCXX/auto-cxx98.cpp clang/test/SemaCXX/class.cpp clang/test/SemaCXX/static-data-member.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 2bbc76fc7..e5b46da65 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4145,7 +4145,7 @@ void Parser::ParseDeclarationSpecifiers(
PrevSpec, DiagID, Policy);
if (!isInvalid && !getLangOpts().C23)
Diag(Tok, diag::ext_auto_storage_class)
- << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
+ << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
} else
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
DiagID, Policy);
|
AaronBallman
left a comment
There was a problem hiding this comment.
I manually verified that all four commits are properly reverted by this single PR, so this LGTM (and needs to be applied to the 23.x release). Thank you for the quick turnaround on this revert!
AaronBallman
left a comment
There was a problem hiding this comment.
Ah, but four reverts might not be enough. Pre-commit CI found this failure:
******************** TEST 'Clang :: SemaCXX/auto-cxx98.cpp' FAILED ********************
Exit Code: 1
Command Output (stdout):
--
# RUN: at line 1
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 -internal-isystem /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/24/include -nostdsysteminc -fsyntax-only -verify /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp -std=c++98 -Wc++11-compat
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 -internal-isystem /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/24/include -nostdsysteminc -fsyntax-only -verify /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp -std=c++98 -Wc++11-compat
# .---command stderr------------
# | error: 'expected-error' diagnostics expected but not seen:
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 14: cannot combine with previous 'typedef' declaration specifier
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 15: cannot combine with previous 'typedef' declaration specifier
# | error: 'expected-error' diagnostics seen but not expected:
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 14: cannot combine with previous 'auto' declaration specifier
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 14: 'auto' not allowed in typedef
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 15: cannot combine with previous 'auto' declaration specifier
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 15: 'auto' not allowed in typedef
# | error: 'expected-warning' diagnostics seen but not expected:
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 14: 'auto' type specifier is a C++11 extension
# | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaCXX/auto-cxx98.cpp Line 15: 'auto' type specifier is a C++11 extension
# | 8 errors generated.
# `-----------------------------
# error: command failed with exit status: 1
--
that file was not updated by any of the links commits.
|
Ah it looks like we need to revert 34436db as well, the functional changes are already covered by the removed code in DeclSpec.cpp, but the test case needs to have its changes backed out. |
This reverts commit 25a419f.
This reverts commit f71a5cc.
…ion (llvm#210347)" This reverts commit 9aeb3a9.
…/C23 (llvm#210141)" This reverts commit 34436db.
…on (llvm#210347)" This reverts commit d592aa5.
This reverts commit 226acaf.
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
This reverts commit 72af746.
Endilll
left a comment
There was a problem hiding this comment.
Changes to C++ DR tests LGTM
AaronBallman
left a comment
There was a problem hiding this comment.
LGTM, thank you! We still need to cherry-pick to 23.x
…8552)" and follow-ups commits (#215320) The initial fix for #164273 had several follow up commits to fix the initial implementation. This fix induces a lot of regressions and a refactoring of the area is required in order to fix the issue in a later release. This reverts the following commits (from oldest to latest): 72af746 226acaf d592aa5 34436db de4b1f5
…m#208552)" and follow-ups commits (llvm#215320) The initial fix for llvm#164273 had several follow up commits to fix the initial implementation. This fix induces a lot of regressions and a refactoring of the area is required in order to fix the issue in a later release. This reverts the following commits (from oldest to latest): 72af746 226acaf d592aa5 34436db de4b1f5
…m#208552)" and follow-ups commits (llvm#215320) The initial fix for llvm#164273 had several follow up commits to fix the initial implementation. This fix induces a lot of regressions and a refactoring of the area is required in order to fix the issue in a later release. This reverts the following commits (from oldest to latest): 72af746 226acaf d592aa5 34436db de4b1f5
The initial fix for #164273 had several follow up commits to fix the initial implementation. This fix induces a lot of regressions and a refactoring of the area is required in order to fix the issue in a later release.
This reverts the following commits (from oldest to latest):
72af746
226acaf
d592aa5
34436db
de4b1f5