llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Vassil Vassilev (vgvassilev)
<details>
<summary>Changes</summary>
AttributeCommonInfo::getAttributeSpellingListIndex() aborts for an unknown
attribute that has a scope, such as [[ns::foo]]. It calls
calculateAttributeSpellingListIndex(), which runs name/scope string-switches
generated for the known attributes. Those switches intentionally have no
default: getScopeFromNormalizedScopeName() falls off the end and hits
llvm_unreachable ("Fell off the end of a string-switch") for the unknown scope.
Any caller that asks a scoped unknown attribute for its spelling index
therefore crashes. An unrecognized attribute has no entry in those tables and
carries a single no-spelling, so short-circuit
calculateAttributeSpellingListIndex() for UnknownAttribute and return index 0
before the switches run.
Add a unit test that constructs an unknown scoped AttributeCommonInfo and asks
for its spelling index; it aborts without the fix.
---
Full diff: https://github.com/llvm/llvm-project/pull/208909.diff
3 Files Affected:
- (modified) clang/lib/Basic/Attributes.cpp (+9)
- (added) clang/unittests/Basic/AttributesTest.cpp (+39)
- (modified) clang/unittests/Basic/CMakeLists.txt (+1)
``````````diff
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 5878a4e3f83a4..8ee45a338c57c 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -240,6 +240,15 @@ getScopeFromNormalizedScopeName(StringRef ScopeName) {
}
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
+ // An unknown attribute (getParsedKind() == UnknownAttribute) has no entry in
+ // the generated spelling tables. The name/scope StringSwitches below assume
a
+ // known attribute and intentionally have no default, so computing an index
+ // for an unknown *scoped* attribute such as [[ns::foo]] would fall off the
+ // end (getScopeFromNormalizedScopeName aborts). It has a single no-spelling,
+ // so report index 0 instead.
+ if (getParsedKind() == AttributeCommonInfo::UnknownAttribute)
+ return 0;
+
// Both variables will be used in tablegen generated
// attribute spell list index matching code.
auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
diff --git a/clang/unittests/Basic/AttributesTest.cpp
b/clang/unittests/Basic/AttributesTest.cpp
new file mode 100644
index 0000000000000..3968be012ad12
--- /dev/null
+++ b/clang/unittests/Basic/AttributesTest.cpp
@@ -0,0 +1,39 @@
+//===- unittests/Basic/AttributesTest.cpp - Attribute parsing tests
-------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/AttributeCommonInfo.h"
+#include "clang/Basic/AttributeScopeInfo.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+
+namespace {
+
+// getAttributeSpellingListIndex() must not crash for an unknown *scoped*
+// attribute such as [[ns::foo]]. Such an attribute has no entry in the
+// generated spelling tables, and the name/scope string-switches used to
compute
+// the index have no default case; the computation must short-circuit for an
+// unknown attribute and report the single no-spelling instead of falling off
+// the end of a switch.
+TEST(AttributesTest, UnknownScopedAttributeSpellingIndex) {
+ LangOptions LangOpts;
+ IdentifierTable Idents(LangOpts);
+ const IdentifierInfo *Name = &Idents.get("foo");
+ const IdentifierInfo *Scope = &Idents.get("ns");
+
+ AttributeCommonInfo CI(Name, AttributeScopeInfo(Scope, SourceLocation()),
+ SourceRange(), AttributeCommonInfo::Form::CXX11());
+
+ ASSERT_EQ(CI.getParsedKind(), AttributeCommonInfo::UnknownAttribute);
+ EXPECT_EQ(CI.getAttributeSpellingListIndex(), 0u);
+}
+
+} // namespace
diff --git a/clang/unittests/Basic/CMakeLists.txt
b/clang/unittests/Basic/CMakeLists.txt
index 32dce09866892..d2f500c6c013e 100644
--- a/clang/unittests/Basic/CMakeLists.txt
+++ b/clang/unittests/Basic/CMakeLists.txt
@@ -2,6 +2,7 @@
# distinct target enables faster iteration times at low cost.
add_distinct_clang_unittest(BasicTests
AtomicLineLoggerTest.cpp
+ AttributesTest.cpp
CharInfoTest.cpp
DarwinSDKInfoTest.cpp
DiagnosticTest.cpp
``````````
</details>
https://github.com/llvm/llvm-project/pull/208909
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits