aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-01-23 16:23:13 +0000
committerDouglas Gregor <dgregor@apple.com>2009-01-23 16:23:13 +0000
commitbe109b3e768b70f9efb106d25d6b5a2c72c5a9b8 (patch)
treebc437157be90c88d16db10e889293de8fb05bfe3
parent562c4d90418996c927f43e89250570d9967d6ecc (diff)
Handle any undeclared parameters in a K&R-style function with a
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
-rw-r--r--include/clang/Parse/Action.h7
-rw-r--r--lib/Parse/Parser.cpp1
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaDecl.cpp16
-rw-r--r--test/Sema/function.c4
-rw-r--r--test/Sema/redefinition.c5
6 files changed, 30 insertions, 4 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 5d87b17221..0f0d88acc8 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -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.
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 6ae3bf038f..7e1cef950f 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -674,6 +674,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
}
// The actions module must verify that all arguments were declared.
+ Actions.ActOnFinishKNRParamDeclarations(CurScope, D);
}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 128ba8813a..40cfe8f193 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -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);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 276f2e24e8..e766ca06a5 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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.
}
diff --git a/test/Sema/function.c b/test/Sema/function.c
index de970a09b3..677f6a3f0e 100644
--- a/test/Sema/function.c
+++ b/test/Sema/function.c
@@ -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'}}
diff --git a/test/Sema/redefinition.c b/test/Sema/redefinition.c
index 5e79070623..97e0473148 100644
--- a/test/Sema/redefinition.c
+++ b/test/Sema/redefinition.c
@@ -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;