]> granicus.if.org Git - clang/commitdiff
Add explicit support for diagnosing implicit function decls.
authorSteve Naroff <snaroff@apple.com>
Fri, 4 Apr 2008 14:32:09 +0000 (14:32 +0000)
committerSteve Naroff <snaroff@apple.com>
Fri, 4 Apr 2008 14:32:09 +0000 (14:32 +0000)
Without this, the diagnostic is very confusing. The diag is now consistent with gcc as well.

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

include/clang/AST/Decl.h
include/clang/Basic/DiagnosticKinds.def
lib/Sema/SemaDecl.cpp
test/Sema/implicit-decl.c [new file with mode: 0644]

index 557a4a25c09d4c94e0e11e2ca5591e903042070c..8197e46c87408f1df642fa89c8ebbc74d97b479e 100644 (file)
@@ -300,13 +300,15 @@ private:
   // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
   unsigned SClass : 2;
   bool IsInline : 1;
+  bool IsImplicit : 1;
   
   FunctionDecl(ContextDecl *CD, SourceLocation L,
                IdentifierInfo *Id, QualType T,
                StorageClass S, bool isInline, ScopedDecl *PrevDecl)
     : ValueDecl(Function, CD, L, Id, T, PrevDecl), 
       ContextDecl(Function),
-      ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {}
+      ParamInfo(0), Body(0), DeclChain(0), SClass(S), 
+      IsInline(isInline), IsImplicit(0) {}
   virtual ~FunctionDecl();
 public:
   static FunctionDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
@@ -317,6 +319,9 @@ public:
   Stmt *getBody() const { return Body; }
   void setBody(Stmt *B) { Body = B; }
   
+  bool isImplicit() { return IsImplicit; }
+  void setImplicit() { IsImplicit = true; }
+  
   ScopedDecl *getDeclChain() const { return DeclChain; }
   void setDeclChain(ScopedDecl *D) { DeclChain = D; }
 
index e8e6fa097eedddde01440704874e44eb354ffd73..f7278d2451dfbcf17746578dd4d2522a67a0491e 100644 (file)
@@ -443,6 +443,8 @@ DIAG(error_duplicate_method_decl, ERROR,
      "duplicate declaration of method '%0'")
 DIAG(err_previous_declaration, ERROR,
      "previous declaration is here")
+DIAG(err_previous_implicit_declaration, ERROR,
+     "previous implicit declaration is here")
 DIAG(err_undeclared_protocol, ERROR,
      "cannot find protocol declaration for '%0'")
 DIAG(err_missing_sel_definition, ERROR,
index 6f0f351000c72b7ff5335e5c5573d549cbb1c40f..882ec0e1a449a901bdd908828374527028e6779b 100644 (file)
@@ -290,8 +290,13 @@ FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
 
   // A function that has already been declared has been redeclared or defined
   // with a different type- show appropriate diagnostic
-  diag::kind PrevDiag = Old->getBody() ? diag::err_previous_definition :
-                                         diag::err_previous_declaration; 
+  diag::kind PrevDiag;
+  if (Old->getBody())
+    PrevDiag = diag::err_previous_definition;
+  else if (Old->isImplicit())
+    PrevDiag = diag::err_previous_implicit_declaration;
+  else
+    PrevDiag = diag::err_previous_declaration;
 
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   // TODO: This is totally simplistic.  It should handle merging functions
@@ -1181,7 +1186,10 @@ ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
   while (S->getParent())
     S = S->getParent();
   
-  return dyn_cast<ScopedDecl>(static_cast<Decl*>(ActOnDeclarator(S, D, 0)));
+  FunctionDecl *FD = 
+    dyn_cast<FunctionDecl>(static_cast<Decl*>(ActOnDeclarator(S, D, 0)));
+  FD->setImplicit();
+  return FD;
 }
 
 
diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c
new file mode 100644 (file)
index 0000000..ea40e61
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: clang %s -verify -fsyntax-only
+
+typedef int int32_t;
+typedef unsigned char Boolean;
+
+void func() {
+   int32_t *vector[16];
+   const char compDesc[16 + 1];
+   int32_t compCount = 0;
+   if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-error{{previous implicit declaration is here}}
+   }
+   return ((void *)0);
+}
+Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}}
+ return 0;
+}
+