Commit 71113fcd by Geoffrey Keating Committed by Geoffrey Keating

re PR c/16622 ([C99] extern inline is handled wrong in C99 mode)

	* c-decl.c (grokdeclarator): Don't set DECL_EXTERNAL on
	inline static functions in c99 mode.

	PR 16622
	* doc/extend.texi (Inline): Update.
	* c-tree.h (struct language_function): Remove field 'extern_inline'.
	* c-decl.c (current_extern_inline): Delete.
	(pop_scope): Adjust test for an undefined nested function.
	Add warning about undeclared inline function.
	(diagnose_mismatched_decls): Update comments.  Disallow overriding
	of inline functions in a translation unit in C99.  Allow inline
	declarations in C99 at any time.
	(merge_decls): Boolize variables.  Handle C99 'extern inline'
	semantics.
	(grokdeclarator): Set DECL_EXTERNAL here for functions.  Handle
	C99 inline semantics.
	(start_function): Don't clear current_extern_inline.  Don't set
	DECL_EXTERNAL.
	(c_push_function_context): Don't push current_extern_inline.
	(c_pop_function_context): Don't restore current_extern_inline.

	PR 11377
	* c-typeck.c (build_external_ref): Warn about static variables
	used in extern inline functions.
	* c-decl.c (start_decl): Warn about static variables declared
	in extern inline functions.

From-SVN: r118356
parent 682d0395
2006-10-31 Geoffrey Keating <geoffk@apple.com>
* c-decl.c (grokdeclarator): Don't set DECL_EXTERNAL on
inline static functions in c99 mode.
PR 16622
* doc/extend.texi (Inline): Update.
* c-tree.h (struct language_function): Remove field 'extern_inline'.
* c-decl.c (current_extern_inline): Delete.
(pop_scope): Adjust test for an undefined nested function.
Add warning about undeclared inline function.
(diagnose_mismatched_decls): Update comments. Disallow overriding
of inline functions in a translation unit in C99. Allow inline
declarations in C99 at any time.
(merge_decls): Boolize variables. Handle C99 'extern inline'
semantics.
(grokdeclarator): Set DECL_EXTERNAL here for functions. Handle
C99 inline semantics.
(start_function): Don't clear current_extern_inline. Don't set
DECL_EXTERNAL.
(c_push_function_context): Don't push current_extern_inline.
(c_pop_function_context): Don't restore current_extern_inline.
PR 11377
* c-typeck.c (build_external_ref): Warn about static variables
used in extern inline functions.
* c-decl.c (start_decl): Warn about static variables declared
in extern inline functions.
2006-10-31 Roger Sayle <roger@eyesopen.com>
PR middle-end/23470
......
......@@ -384,7 +384,6 @@ struct language_function GTY(())
int returns_null;
int returns_abnormally;
int warn_about_return_type;
int extern_inline;
};
/* Save lists of labels used or defined in particular contexts.
......
......@@ -2109,6 +2109,17 @@ build_external_ref (tree id, int fun, location_t loc)
if (context != 0 && context != current_function_decl)
DECL_NONLOCAL (ref) = 1;
}
/* C99 6.7.4p3: An inline definition of a function with external
linkage ... shall not contain a reference to an identifier with
internal linkage. */
else if (current_function_decl != 0
&& DECL_DECLARED_INLINE_P (current_function_decl)
&& DECL_EXTERNAL (current_function_decl)
&& VAR_OR_FUNCTION_DECL_P (ref)
&& (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref))
&& ! TREE_PUBLIC (ref))
pedwarn ("%H%qD is static but used in inline function %qD "
"which is not static", &loc, ref, current_function_decl);
return ref;
}
......
2006-10-31 Geoffrey Keating <geoffk@apple.com>
* gcc.dg/inline-16.c: New.
PR 16622
* gcc.dg/inline-10.c (main): Don't declare 'main' inline without
defining it.
* gcc.dg/inline-13.c: New.
* gcc.dg/inline-14.c: New.
* gcc.dg/inline-15.c: New.
PR 11377
* gcc.dg/inline6.c: New.
* gcc.dg/inline7.c: New.
2006-10-31 Roger Sayle <roger@eyesopen.com>
PR middle-end/23470
......@@ -3,4 +3,4 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -ffreestanding -pedantic-errors" } */
inline int main (void);
inline int main (void) { return 1; }
/* Verify basic C99 inline functionality. */
/* { dg-do compile } */
/* { dg-options "-std=c99" } */
/* { dg-final { scan-assembler-not "dontgenerate" } } */
/* { dg-final { scan-assembler "func1" } } */
/* { dg-final { scan-assembler "func2" } } */
/* { dg-final { scan-assembler "func3" } } */
/* { dg-final { scan-assembler "func4" } } */
/* { dg-final { scan-assembler "func5" } } */
/* { dg-final { scan-assembler "func6" } } */
/* { dg-final { scan-assembler "func7" } } */
/* { dg-final { scan-assembler "func8" } } */
/* { dg-final { scan-assembler "func9" } } */
inline int dontgenerate1 (void)
{
return 1;
}
inline int dontgenerate2 (void);
inline int dontgenerate2 (void)
{
return 2;
}
inline int dontgenerate3 (void)
{
return 3;
}
inline int dontgenerate3 (void);
extern inline int func1 (void) { return 1; }
extern inline int func2 (void);
inline int func2 (void) { return 2; }
inline int func3 (void) { return 3; }
extern inline int func3 (void);
inline int func4 (void);
extern inline int func4 (void) { return 4; }
extern inline int func5 (void) { return 5; }
inline int func5 (void);
extern int func6 (void);
inline int func6 (void) { return 6; }
inline int func7 (void) { return 7; }
extern int func7 (void);
inline int func8 (void);
extern int func8 (void) { return 8; }
extern int func9 (void) { return 9; }
inline int func9 (void);
/* Check that you can't redefine a C99 inline function. */
/* { dg-do compile } */
/* { dg-options "-std=c99" } */
extern inline int func1 (void)
{ /* { dg-error "previous definition" } */
return 1;
}
inline int func1 (void)
{ /* { dg-error "redefinition" } */
return 1;
}
inline int func2 (void)
{ /* { dg-error "previous definition" } */
return 2;
}
inline int func2 (void)
{ /* { dg-error "redefinition" } */
return 2;
}
/* Check that an error message is produced when a C99 inline function
is never defined. */
/* { dg-do compile } */
/* { dg-options "-std=c99" } */
extern inline int func1 (void); /* { dg-error "never defined" } */
inline int func2 (void); /* { dg-error "never defined" } */
/* { dg-do link } */
/* { dg-options "-std=c99" } */
static inline int
func1(const volatile void * base, int byteOffset)
{
volatile int *addr = (volatile int *)((int)base + byteOffset);
return *addr;
}
static inline int
func2(int data)
{
return func1(&data, 0);
}
int main(int argc, char *argv[]) {
int b = func2(argc);
return 0;
}
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } */
static int i;
extern int j;
extern inline int func1 (void) {
return i++; /* { dg-warning "static" } */
}
extern inline int func2 (void) {
return j++;
}
inline int func3 (void)
{
return i++;
}
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } */
extern inline void func1 (void) {
static int i; /* { dg-warning "static" } */
}
inline void func3 (void)
{
static int i;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment