<div dir="ltr">Can we merge this to 3.5, or are we done merging patches?</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Aug 27, 2014 at 2:27 PM, Hans Wennborg <span dir="ltr"><<a href="mailto:hans@hanshq.net" target="_blank">hans@hanshq.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: hans<br>
Date: Wed Aug 27 16:27:40 2014<br>
New Revision: 216619<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=216619&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=216619&view=rev</a><br>
Log:<br>
Allow adding dll attributes on certain redecls with a warning if the decl hasn't been used yet (PR20746)<br>
<br>
This shouldn't really be allowed, but it comes up in real code (see PR). As<br>
long as the decl hasn't been used there's no technical difficulty in supporting<br>
it, so downgrade the error to a warning.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D5087" target="_blank">http://reviews.llvm.org/D5087</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/test/Sema/dllexport.c<br>
    cfe/trunk/test/Sema/dllimport.c<br>
    cfe/trunk/test/SemaCXX/dllexport.cpp<br>
    cfe/trunk/test/SemaCXX/dllimport.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=216619&r1=216618&r2=216619&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=216619&r1=216618&r2=216619&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Aug 27 16:27:40 2014<br>
@@ -2133,6 +2133,9 @@ def warn_attribute_invalid_on_definition<br>
   InGroup<IgnoredAttributes>;<br>
 def err_attribute_dll_redeclaration : Error<<br>
   "redeclaration of %q0 cannot add %q1 attribute">;<br>
+def warn_attribute_dll_redeclaration : Warning<<br>
+  "redeclaration of %q0 should not add %q1 attribute">,<br>
+  InGroup<DiagGroup<"dll-attribute-on-redeclaration">>;<br>
 def err_attribute_dllimport_function_definition : Error<<br>
   "dllimport cannot be applied to non-inline function definition">;<br>
 def err_attribute_dll_deleted : Error<<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=216619&r1=216618&r2=216619&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=216619&r1=216618&r2=216619&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Aug 27 16:27:40 2014<br>
@@ -5075,7 +5075,7 @@ static void checkDLLAttributeRedeclarati<br>
     NewDecl = NewTD->getTemplatedDecl();<br>
<br>
   if (!OldDecl || !NewDecl)<br>
-      return;<br>
+    return;<br>
<br>
   const DLLImportAttr *OldImportAttr = OldDecl->getAttr<DLLImportAttr>();<br>
   const DLLExportAttr *OldExportAttr = OldDecl->getAttr<DLLExportAttr>();<br>
@@ -5092,13 +5092,30 @@ static void checkDLLAttributeRedeclarati<br>
   // Implicitly generated declarations are also excluded for now because there<br>
   // is no other way to switch these to use dllimport or dllexport.<br>
   bool AddsAttr = !(OldImportAttr || OldExportAttr) && HasNewAttr;<br>
+<br>
   if (AddsAttr && !IsSpecialization && !OldDecl->isImplicit()) {<br>
-    S.Diag(NewDecl->getLocation(), diag::err_attribute_dll_redeclaration)<br>
-      << NewDecl<br>
-      << (NewImportAttr ? (const Attr *)NewImportAttr : NewExportAttr);<br>
+    // If the declaration hasn't been used yet, allow with a warning for<br>
+    // free functions and global variables.<br>
+    bool JustWarn = false;<br>
+    if (!OldDecl->isUsed() && OldDecl->getDeclContext()->isFileContext()) {<br>
+      auto *VD = dyn_cast<VarDecl>(OldDecl);<br>
+      if (VD && !VD->getDescribedVarTemplate())<br>
+        JustWarn = true;<br>
+      auto *FD = dyn_cast<FunctionDecl>(OldDecl);<br>
+      if (FD && FD->getTemplatedKind() == FunctionDecl::TK_NonTemplate)<br>
+        JustWarn = true;<br>
+    }<br>
+<br>
+    unsigned DiagID = JustWarn ? diag::warn_attribute_dll_redeclaration<br>
+                               : diag::err_attribute_dll_redeclaration;<br>
+    S.Diag(NewDecl->getLocation(), DiagID)<br>
+        << NewDecl<br>
+        << (NewImportAttr ? (const Attr *)NewImportAttr : NewExportAttr);<br>
     S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);<br>
-    NewDecl->setInvalidDecl();<br>
-    return;<br>
+    if (!JustWarn) {<br>
+      NewDecl->setInvalidDecl();<br>
+      return;<br>
+    }<br>
   }<br>
<br>
   // A redeclaration is not allowed to drop a dllimport attribute, the only<br>
<br>
Modified: cfe/trunk/test/Sema/dllexport.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllexport.c?rev=216619&r1=216618&r2=216619&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllexport.c?rev=216619&r1=216618&r2=216619&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/dllexport.c (original)<br>
+++ cfe/trunk/test/Sema/dllexport.c Wed Aug 27 16:27:40 2014<br>
@@ -39,8 +39,13 @@ __declspec(dllexport) extern int GlobalR<br>
                              int GlobalRedecl2;<br>
<br>
                       extern int GlobalRedecl3; // expected-note{{previous declaration is here}}<br>
+int useGlobalRedecl3() { return GlobalRedecl3; }<br>
 __declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}<br>
<br>
+                      extern int GlobalRedecl4; // expected-note{{previous declaration is here}}<br>
+__declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}}<br>
+<br>
+<br>
 // External linkage is required.<br>
 __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}<br>
<br>
@@ -86,11 +91,18 @@ __declspec(dllexport) void redecl3();<br>
                       void redecl3() {}<br>
<br>
                       void redecl4(); // expected-note{{previous declaration is here}}<br>
+void useRedecl4() { redecl4(); }<br>
 __declspec(dllexport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}}<br>
<br>
                       void redecl5(); // expected-note{{previous declaration is here}}<br>
+void useRedecl5() { redecl5(); }<br>
 __declspec(dllexport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllexport' attribute}}<br>
<br>
+// Allow with a warning if the decl hasn't been used yet.<br>
+                      void redecl6(); // expected-note{{previous declaration is here}}<br>
+__declspec(dllexport) void redecl6(); // expected-warning{{redeclaration of 'redecl6' should not add 'dllexport' attribute}}<br>
+<br>
+<br>
 // External linkage is required.<br>
 __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}<br>
<br>
<br>
Modified: cfe/trunk/test/Sema/dllimport.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport.c?rev=216619&r1=216618&r2=216619&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport.c?rev=216619&r1=216618&r2=216619&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/dllimport.c (original)<br>
+++ cfe/trunk/test/Sema/dllimport.c Wed Aug 27 16:27:40 2014<br>
@@ -64,9 +64,16 @@ int GlobalRedecl2c __attribute__((dllimp<br>
 __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}<br>
                       extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}<br>
<br>
+// Adding an attribute on redeclaration.<br>
                       extern int GlobalRedecl4; // expected-note{{previous declaration is here}}<br>
+int useGlobalRedecl4() { return GlobalRedecl4; }<br>
 __declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}<br>
<br>
+// Allow with a warning if the decl hasn't been used yet.<br>
+                      extern int GlobalRedecl5; // expected-note{{previous declaration is here}}<br>
+__declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}}<br>
+<br>
+<br>
 // External linkage is required.<br>
 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}<br>
<br>
@@ -128,14 +135,20 @@ __declspec(dllimport) void redecl3(); //<br>
                       void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}<br>
<br>
                       void redecl4(); // expected-note{{previous declaration is here}}<br>
+void useRedecl4() { redecl4(); }<br>
 __declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}<br>
<br>
+// Allow with a warning if the decl hasn't been used yet.<br>
+                      void redecl5(); // expected-note{{previous declaration is here}}<br>
+__declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}<br>
+<br>
+<br>
 // Inline redeclarations are fine.<br>
-__declspec(dllimport) void redecl5();<br>
-                      inline void redecl5() {}<br>
+__declspec(dllimport) void redecl6();<br>
+                      inline void redecl6() {}<br>
<br>
-                      void redecl6(); // expected-note{{previous declaration is here}}<br>
-__declspec(dllimport) inline void redecl6() {} // expected-error{{redeclaration of 'redecl6' cannot add 'dllimport' attribute}}<br>
+                      void redecl7(); // expected-note{{previous declaration is here}}<br>
+__declspec(dllimport) inline void redecl7() {} // expected-warning{{redeclaration of 'redecl7' should not add 'dllimport' attribute}}<br>
<br>
 // External linkage is required.<br>
 __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/dllexport.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=216619&r1=216618&r2=216619&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=216619&r1=216618&r2=216619&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/dllexport.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/dllexport.cpp Wed Aug 27 16:27:40 2014<br>
@@ -53,7 +53,7 @@ __declspec(dllexport) extern int GlobalR<br>
                              int GlobalRedecl2;<br>
<br>
                       extern int GlobalRedecl3; // expected-note{{previous declaration is here}}<br>
-__declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}<br>
+__declspec(dllexport) extern int GlobalRedecl3; // expected-warning{{redeclaration of 'GlobalRedecl3' should not add 'dllexport' attribute}}<br>
<br>
 // External linkage is required.<br>
 __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}<br>
@@ -186,10 +186,10 @@ __declspec(dllexport) void redecl2();<br>
                       void redecl2() {}<br>
<br>
                       void redecl3(); // expected-note{{previous declaration is here}}<br>
-__declspec(dllexport) void redecl3(); // expected-error{{redeclaration of 'redecl3' cannot add 'dllexport' attribute}}<br>
+__declspec(dllexport) void redecl3(); // expected-warning{{redeclaration of 'redecl3' should not add 'dllexport' attribute}}<br>
<br>
                       void redecl4(); // expected-note{{previous declaration is here}}<br>
-__declspec(dllexport) inline void redecl4() {} // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}}<br>
+__declspec(dllexport) inline void redecl4() {} // expected-warning{{redeclaration of 'redecl4' should not add 'dllexport' attribute}}<br>
<br>
 // Friend functions<br>
 struct FuncFriend {<br>
@@ -200,8 +200,8 @@ struct FuncFriend {<br>
 };<br>
 __declspec(dllexport) void friend1() {}<br>
                       void friend2() {}<br>
-__declspec(dllexport) void friend3() {} // expected-error{{redeclaration of 'friend3' cannot add 'dllexport' attribute}}<br>
-__declspec(dllexport) inline void friend4() {} // expected-error{{redeclaration of 'friend4' cannot add 'dllexport' attribute}}<br>
+__declspec(dllexport) void friend3() {} // expected-warning{{redeclaration of 'friend3' should not add 'dllexport' attribute}}<br>
+__declspec(dllexport) inline void friend4() {} // expected-warning{{redeclaration of 'friend4' should not add 'dllexport' attribute}}<br>
<br>
 // Implicit declarations can be redeclared with dllexport.<br>
 __declspec(dllexport) void* operator new(__SIZE_TYPE__ n);<br>
<br>
Modified: cfe/trunk/test/SemaCXX/dllimport.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=216619&r1=216618&r2=216619&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=216619&r1=216618&r2=216619&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/dllimport.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Wed Aug 27 16:27:40 2014<br>
@@ -75,7 +75,7 @@ __declspec(dllimport) extern int GlobalR<br>
                       extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}<br>
<br>
                       extern int GlobalRedecl4; // expected-note{{previous declaration is here}}<br>
-__declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}<br>
+__declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}}<br>
<br>
 // External linkage is required.<br>
 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}<br>
@@ -224,10 +224,10 @@ __declspec(dllimport) void redecl3(); //<br>
                       void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}<br>
<br>
                       void redecl4(); // expected-note{{previous declaration is here}}<br>
-__declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}<br>
+__declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}}<br>
<br>
                       void redecl5(); // expected-note{{previous declaration is here}}<br>
-__declspec(dllimport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllimport' attribute}}<br>
+__declspec(dllimport) inline void redecl5() {} // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}<br>
<br>
 // Friend functions<br>
 struct FuncFriend {<br>
@@ -240,8 +240,8 @@ struct FuncFriend {<br>
 __declspec(dllimport) void friend1();<br>
                       void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}<br>
                       void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}<br>
-__declspec(dllimport) void friend4(); // expected-error{{redeclaration of 'friend4' cannot add 'dllimport' attribute}}<br>
-__declspec(dllimport) inline void friend5() {} // expected-error{{redeclaration of 'friend5' cannot add 'dllimport' attribute}}<br>
+__declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}}<br>
+__declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}}<br>
<br>
 void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}<br>
 void __declspec(dllimport) friend7();<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>