]> granicus.if.org Git - clang/commitdiff
Do not use the incorrect attribute spelling list index when translating a no_sanitize...
authorAaron Ballman <aaron@aaronballman.com>
Tue, 21 May 2019 17:24:49 +0000 (17:24 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Tue, 21 May 2019 17:24:49 +0000 (17:24 +0000)
This fixes a crash when AST pretty printing declarations marked with no_sanitize_memory.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361274 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclAttr.cpp
test/AST/ast-print-no-sanitize.cpp [new file with mode: 0644]

index f8a34573f3c828b2101842e000d8e09fa7f4a30b..03b38bf2158dde091ead95243df08af65d8a22b8 100644 (file)
@@ -6329,9 +6329,21 @@ static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
   if (isGlobalVar(D) && SanitizerName != "address")
     S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
         << AL << ExpectedFunction;
-  D->addAttr(::new (S.Context)
-                 NoSanitizeAttr(AL.getRange(), S.Context, &SanitizerName, 1,
-                                AL.getAttributeSpellingListIndex()));
+
+  // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
+  // NoSanitizeAttr object; but we need to calculate the correct spelling list
+  // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
+  // has the same spellings as the index for NoSanitizeAttr. We don't have a
+  // general way to "translate" between the two, so this hack attempts to work
+  // around the issue with hard-coded indicies. This is critical for calling
+  // getSpelling() or prettyPrint() on the resulting semantic attribute object
+  // without failing assertions.
+  unsigned TranslatedSpellingIndex = 0;
+  if (AL.isC2xAttribute() || AL.isCXX11Attribute())
+    TranslatedSpellingIndex = 1;
+
+  D->addAttr(::new (S.Context) NoSanitizeAttr(
+      AL.getRange(), S.Context, &SanitizerName, 1, TranslatedSpellingIndex));
 }
 
 static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
diff --git a/test/AST/ast-print-no-sanitize.cpp b/test/AST/ast-print-no-sanitize.cpp
new file mode 100644 (file)
index 0000000..4ff9719
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++11 -ast-print %s -o - | FileCheck %s
+
+void should_not_crash_1() __attribute__((no_sanitize_memory));
+[[clang::no_sanitize_memory]] void should_not_crash_2();
+
+// CHECK: void should_not_crash_1() __attribute__((no_sanitize("memory")));
+// CHECK: void should_not_crash_2() {{\[\[}}clang::no_sanitize("memory"){{\]\]}};