]> granicus.if.org Git - clang/commitdiff
Handle any undeclared parameters in a K&R-style function with a
authorDouglas Gregor <dgregor@apple.com>
Fri, 23 Jan 2009 16:23:13 +0000 (16:23 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 23 Jan 2009 16:23:13 +0000 (16:23 +0000)
special action, inside function prototype scope. This avoids confusion
when we try to inject these parameters into the scope of the function
body before the function itself has been added to the surrounding
scope. Fixes <rdar://problem/6097326>.

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

include/clang/Parse/Action.h
lib/Parse/Parser.cpp
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
test/Sema/function.c
test/Sema/redefinition.c

index 5d87b1722105d1dda1ae1e4dc00795f67a2c3413..0f0d88acc84ecb7878bfba56f0f54fc417dc044a 100644 (file)
@@ -223,6 +223,13 @@ public:
     return Group;
   }
 
+  /// @brief Indicates that all K&R-style parameter declarations have
+  /// been parsed prior to a function definition.
+  /// @param S  The function prototype scope.
+  /// @param D  The function declarator.
+  virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D) {
+  }
+
   /// ActOnStartOfFunctionDef - This is called at the start of a function
   /// definition, instead of calling ActOnDeclarator.  The Declarator includes
   /// information about formal arguments that are part of this function.
index 6ae3bf038ffa55a0a3d5d05a2ab7b3475b770ae4..7e1cef950fdc2e86d6745e5fc63f99a15b4b72c1 100644 (file)
@@ -674,6 +674,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
   }
 
   // The actions module must verify that all arguments were declared.
+  Actions.ActOnFinishKNRParamDeclarations(CurScope, D);
 }
 
 
index 128ba8813a1f1a3f0c1eff6c1fcb4de427e90355..40cfe8f1938a07d2065e1dd20ff6c76910a52a64 100644 (file)
@@ -311,6 +311,7 @@ public:
   void ActOnUninitializedDecl(DeclTy *dcl);
   virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
 
+  virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D);
   virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, DeclTy *D);
   virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
index 276f2e24e85dd782c281c0d58fec34824f6415e9..e766ca06a5e11577d90da3592eedb553bbe20ac5 100644 (file)
@@ -2633,8 +2633,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
 
 }
 
-Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
-  assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D) {
   assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "Not a function declarator!");
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
@@ -2654,10 +2653,19 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
                            PrevSpec);
         Declarator ParamD(DS, Declarator::KNRTypeListContext);
         ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc);
-        FTI.ArgInfo[i].Param = ActOnParamDeclarator(FnBodyScope, ParamD);
+        FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD);
       }
     }
-  } else {
+  } 
+}
+
+Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
+  assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+  assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "Not a function declarator!");
+  DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+  if (FTI.hasPrototype) {
     // FIXME: Diagnose arguments without names in C. 
   }
   
index de970a09b352f2f5f1be20514676a2d502f342a1..677f6a3f0e294acf9c23be2f31b43c33554cb81a 100644 (file)
@@ -39,3 +39,7 @@ void t13() {
 int t14() {
   return; // expected-warning {{non-void function 't14' should return a value}}
 }
+
+// <rdar://problem/6097326>
+y(y) { return y; } // expected-warning{{parameter 'y' was not declared, defaulting to type 'int'}} \
+                   // expected-warning{{type specifier missing, defaults to 'int'}}
index 5e7907062311c7f80f55b14bf6daf7f293bf19ea..97e047314803728f12ecf0da61fa5cd56efa2d91 100644 (file)
@@ -3,3 +3,8 @@ int f(int a) { } // expected-note {{previous definition is here}}
 int f(int);
 int f(int a) { } // expected-error {{redefinition of 'f'}}
 
+// <rdar://problem/6097326>
+int foo(x) {
+  return 0;
+}
+int x = 1;