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

Reply via email to