This patch delays the call to Sema::checkAttributesAfterMerging to delay
linkage computation. This has already been done once in the past, but
when auto is involved this is not enough and something like the
following crashes:
namespace { class Internal {}; }
__attribute__((weak)) auto f = Internal();
-Nico
>From 24b6fe325786d5c3e78d36b1c50cbdf1337f403f Mon Sep 17 00:00:00 2001
From: Nico Rieck <[email protected]>
Date: Tue, 21 Jan 2014 19:05:14 +0100
Subject: [PATCH] Delay attribute checking until auto types are deduced
Checking in ActOnVariableDeclarator computes and caches the linkage using
the non-deduced auto type which defaults to external linkage. Depending on
how the auto type is deduced linkage can change and conflict with the
cached linkage, hitting asserts.
---
lib/Sema/SemaDecl.cpp | 7 ++++++-
test/SemaCXX/attr-selectany.cpp | 5 ++++-
test/SemaCXX/attr-weak.cpp | 6 ++++--
test/SemaCXX/attr-weakref.cpp | 4 +++-
4 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c5afe3b..7d6190d 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4816,6 +4816,10 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
}
static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
+ // Ensure that an auto decl is deduced otherwise the checks below might cache
+ // the wrong linkage.
+ assert(S.ParsingInitForAutoVars.count(&ND) == 0);
+
// 'weak' only applies to declarations with external linkage.
if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) {
if (!ND.isExternallyVisible()) {
@@ -5514,7 +5518,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
ProcessPragmaWeak(S, NewVD);
- checkAttributesAfterMerging(*this, *NewVD);
// If this is the first declaration of an extern C variable, update
// the map of such variables.
@@ -8996,6 +8999,8 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
if (!VD)
return;
+ checkAttributesAfterMerging(*this, *VD);
+
if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp
index 0f9776d..c27a915 100644
--- a/test/SemaCXX/attr-selectany.cpp
+++ b/test/SemaCXX/attr-selectany.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -std=c++11 %s
// MSVC produces similar diagnostics.
__declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
@@ -31,3 +31,6 @@ class X {
};
__declspec(selectany) X x(1);
+
+namespace { class Internal {}; }
+__declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}}
diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp
index 2000e7f..8ba3a95 100644
--- a/test/SemaCXX/attr-weak.cpp
+++ b/test/SemaCXX/attr-weak.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
@@ -31,8 +31,10 @@ template <class T> struct Test7 {
};
template <class T>
int Test7<T>::var;
-namespace { class Internal; }
+namespace { class Internal {}; }
template struct Test7<Internal>;
template struct Test7<int>;
class __attribute__((weak)) Test8 {}; // OK
+
+__attribute__((weak)) auto Test9 = Internal(); // expected-error {{weak declaration cannot have internal linkage}}
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
index 0c3f1d2..46ca5ab 100644
--- a/test/SemaCXX/attr-weakref.cpp
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
@@ -34,3 +34,5 @@ static int a10();
int a10() __attribute__((weakref ("foo")));
static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}
+
+__attribute__((weakref ("foo"))) auto a11 = 1; // expected-error {{weakref declaration must have internal linkage}}
--
1.8.1.msysgit.1
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits