On 03.02.2012 23:57, Eli Friedman wrote:
On Fri, Feb 3, 2012 at 11:34 AM, Anton Yartsev<[email protected]>  wrote:
On 03.02.2012 2:34, Eli Friedman wrote:
On Wed, Feb 1, 2012 at 9:33 PM, Eli Friedman<[email protected]>
  wrote:
On Wed, Feb 1, 2012 at 9:13 PM, Anton Yartsev<[email protected]>
  wrote:
Author: ayartsev
Date: Wed Feb  1 23:13:59 2012
New Revision: 149587

URL: http://llvm.org/viewvc/llvm-project?rev=149587&view=rev
Log:
Fix for PR10657 (http://llvm.org/bugs/show_bug.cgi?id=10657)
extern inline case considered

Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/test/CodeGen/inline.c
    cfe/trunk/test/CodeGen/inline2.c
The changes you are making to the tests are clearly wrong.  Please
revert, and we can discuss the correct way to fix your testcase.
I just took a quick look; a correct patch would probably involve
changing FunctionDecl::doesDeclarationForceExternallyVisibleDefinition
.

-Eli
Previous commit was awful, sorry. Attached is an adequate patch. Ok to
commit?
Better... comments below:

-// No PR#, but this once crashed clang in C99 mode due to buggy extern inline
-// redeclaration detection.
-void test7() { }
+// PR10657
+extern __inline void test7() {}
  void test7();

Please make your new test a separate test; we want as much coverage as
possible here.

Just to double-check, does your patch work correctly with the following test?

void test();
__inline void test() {}
  void test();

-Eli
Did you mean "extern __inline"?
The patch works fine - no crush, the definition is generated.
Updated the test, new patch attached

--
Anton

Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp	(revision 149702)
+++ lib/AST/Decl.cpp	(working copy)
@@ -1895,17 +1895,21 @@
   ASTContext &Context = getASTContext();
 
   // In C99 mode, a function may have an inline definition (causing it to
-  // be deferred) then redeclared later.  As a special case, "extern inline"
-  // is not required to produce an external symbol.
+  // be deferred) then redeclared later. 
+  // If all of the file scope declarations for a function in a translation unit
+  // include the inline function specifier without extern, then the definition
+  // in that translation unit is an inline definition. A file scope declaration 
+  // with extern creates an external definition. (C99 6.7.4p6,7)
   if (Context.getLangOptions().GNUInline || !Context.getLangOptions().C99 ||
       Context.getLangOptions().CPlusPlus)
     return false;
-  if (getLinkage() != ExternalLinkage || isInlineSpecified())
+  if (getStorageClassAsWritten() != SC_Extern)
     return false;
   const FunctionDecl *Definition = 0;
   if (hasBody(Definition))
     return Definition->isInlined() &&
-           Definition->isInlineDefinitionExternallyVisible();
+           (Definition->getStorageClassAsWritten() != SC_Extern);
+
   return false;
 }
 
Index: test/CodeGen/inline.c
===================================================================
--- test/CodeGen/inline.c	(revision 149702)
+++ test/CodeGen/inline.c	(working copy)
@@ -102,3 +102,7 @@
 // PR11062; the fact that the function is named strlcpy matters here.
 inline __typeof(sizeof(int)) strlcpy(char *dest, const char *src, __typeof(sizeof(int)) size) { return 3; }
 void test8() { strlcpy(0,0,0); }
+
+// PR10657; the test crushed in C99 mode
+extern inline void test9() { }
+void test9();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to