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
This commit is contained in:
parent
682d039597
commit
71113fcd70
@ -1,3 +1,32 @@
|
||||
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
|
||||
|
127
gcc/c-decl.c
127
gcc/c-decl.c
@ -154,10 +154,6 @@ int current_function_returns_abnormally;
|
||||
|
||||
static int warn_about_return_type;
|
||||
|
||||
/* Nonzero when starting a function declared `extern inline'. */
|
||||
|
||||
static int current_extern_inline;
|
||||
|
||||
/* Nonzero when the current toplevel function contains a declaration
|
||||
of a nested function which is never defined. */
|
||||
|
||||
@ -797,11 +793,22 @@ pop_scope (void)
|
||||
&& DECL_ABSTRACT_ORIGIN (p) != p)
|
||||
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
|
||||
if (!DECL_EXTERNAL (p)
|
||||
&& DECL_INITIAL (p) == 0)
|
||||
&& !DECL_INITIAL (p)
|
||||
&& scope != file_scope
|
||||
&& scope != external_scope)
|
||||
{
|
||||
error ("nested function %q+D declared but never defined", p);
|
||||
undef_nested_function = true;
|
||||
}
|
||||
/* C99 6.7.4p6: "a function with external linkage... declared
|
||||
with an inline function specifier ... shall also be defined in the
|
||||
same translation unit." */
|
||||
else if (DECL_DECLARED_INLINE_P (p)
|
||||
&& TREE_PUBLIC (p)
|
||||
&& !DECL_INITIAL (p)
|
||||
&& flag_isoc99)
|
||||
pedwarn ("inline function %q+D declared but never defined", p);
|
||||
|
||||
goto common_symbol;
|
||||
|
||||
case VAR_DECL:
|
||||
@ -1292,10 +1299,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
|
||||
|
||||
/* Function declarations can either be 'static' or 'extern' (no
|
||||
qualifier is equivalent to 'extern' - C99 6.2.2p5) and therefore
|
||||
can never conflict with each other on account of linkage (6.2.2p4).
|
||||
Multiple definitions are not allowed (6.9p3,5) but GCC permits
|
||||
two definitions if one is 'extern inline' and one is not. The non-
|
||||
extern-inline definition supersedes the extern-inline definition. */
|
||||
can never conflict with each other on account of linkage
|
||||
(6.2.2p4). Multiple definitions are not allowed (6.9p3,5) but
|
||||
gnu89 mode permits two definitions if one is 'extern inline' and
|
||||
one is not. The non- extern-inline definition supersedes the
|
||||
extern-inline definition. */
|
||||
|
||||
else if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
@ -1321,16 +1329,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
|
||||
{
|
||||
/* If both decls are in the same TU and the new declaration
|
||||
isn't overriding an extern inline reject the new decl.
|
||||
When we handle c99 style inline rules we'll want to reject
|
||||
the following:
|
||||
|
||||
DECL_EXTERN_INLINE (olddecl)
|
||||
&& !DECL_EXTERN_INLINE (newdecl)
|
||||
|
||||
if they're in the same translation unit. Until we implement
|
||||
the full semantics we accept the construct. */
|
||||
if (!(DECL_EXTERN_INLINE (olddecl)
|
||||
&& !DECL_EXTERN_INLINE (newdecl))
|
||||
In c99, no overriding is allowed in the same translation
|
||||
unit. */
|
||||
if ((!DECL_EXTERN_INLINE (olddecl)
|
||||
|| DECL_EXTERN_INLINE (newdecl)
|
||||
|| flag_isoc99)
|
||||
&& same_translation_unit_p (newdecl, olddecl))
|
||||
{
|
||||
error ("redefinition of %q+D", newdecl);
|
||||
@ -1521,9 +1524,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
|
||||
??? Should we still warn about this now we have unit-at-a-time
|
||||
mode and can get it right?
|
||||
Definitely don't complain if the decls are in different translation
|
||||
units. */
|
||||
units.
|
||||
C99 permits this, so don't warn in that case. (The function
|
||||
may not be inlined everywhere in function-at-a-time mode, but
|
||||
we still shouldn't warn.) */
|
||||
if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
|
||||
&& same_translation_unit_p (olddecl, newdecl))
|
||||
&& same_translation_unit_p (olddecl, newdecl)
|
||||
&& ! flag_isoc99)
|
||||
{
|
||||
if (TREE_USED (olddecl))
|
||||
{
|
||||
@ -1600,12 +1607,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
|
||||
static void
|
||||
merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
||||
{
|
||||
int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& DECL_INITIAL (newdecl) != 0);
|
||||
int new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0);
|
||||
int old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0);
|
||||
bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& DECL_INITIAL (newdecl) != 0);
|
||||
bool new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0);
|
||||
bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0);
|
||||
bool extern_changed = false;
|
||||
|
||||
/* For real parm decl following a forward decl, rechain the old decl
|
||||
in its new location and clear TREE_ASM_WRITTEN (it's not a
|
||||
@ -1752,6 +1760,18 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
||||
}
|
||||
}
|
||||
|
||||
/* In c99, 'extern' declaration before (or after) 'inline' means this
|
||||
function is not DECL_EXTERNAL. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& (DECL_DECLARED_INLINE_P (newdecl)
|
||||
|| DECL_DECLARED_INLINE_P (olddecl))
|
||||
&& (!DECL_DECLARED_INLINE_P (newdecl)
|
||||
|| !DECL_DECLARED_INLINE_P (olddecl)
|
||||
|| !DECL_EXTERNAL (olddecl))
|
||||
&& DECL_EXTERNAL (newdecl)
|
||||
&& flag_isoc99)
|
||||
DECL_EXTERNAL (newdecl) = 0;
|
||||
|
||||
if (DECL_EXTERNAL (newdecl))
|
||||
{
|
||||
TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
|
||||
@ -1844,6 +1864,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
||||
}
|
||||
}
|
||||
|
||||
extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
|
||||
|
||||
/* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
|
||||
But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */
|
||||
{
|
||||
@ -1886,6 +1908,13 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
||||
|| (TREE_CODE (olddecl) == VAR_DECL
|
||||
&& TREE_STATIC (olddecl))))
|
||||
make_decl_rtl (olddecl);
|
||||
|
||||
/* If we changed a function from DECL_EXTERNAL to !DECL_EXTERNAL,
|
||||
and the definition is coming from the old version, cgraph needs
|
||||
to be called again. */
|
||||
if (extern_changed && !new_is_definition
|
||||
&& TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl))
|
||||
cgraph_finalize_function (olddecl, false);
|
||||
}
|
||||
|
||||
/* Handle when a new declaration NEWDECL has the same name as an old
|
||||
@ -3282,6 +3311,17 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
|
||||
warning (OPT_Wattributes, "inline function %q+D given attribute noinline",
|
||||
decl);
|
||||
|
||||
/* C99 6.7.4p3: An inline definition of a function with external
|
||||
linkage shall not contain a definition of a modifiable object
|
||||
with static storage duration... */
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& current_scope != file_scope
|
||||
&& TREE_STATIC (decl)
|
||||
&& DECL_DECLARED_INLINE_P (current_function_decl)
|
||||
&& DECL_EXTERNAL (current_function_decl))
|
||||
pedwarn ("%q+D is static but declared in inline function %qD "
|
||||
"which is not static", decl, current_function_decl);
|
||||
|
||||
/* Add this decl to the current scope.
|
||||
TEM may equal DECL or it may be a previous decl of the same name. */
|
||||
tem = pushdecl (decl);
|
||||
@ -4726,8 +4766,15 @@ grokdeclarator (const struct c_declarator *declarator,
|
||||
GCC to signify a forward declaration of a nested function. */
|
||||
if (storage_class == csc_auto && current_scope != file_scope)
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
/* In C99, a function which is declared 'inline' with 'extern'
|
||||
is not an external reference (which is confusing). It
|
||||
means that the later definition of the function must be output
|
||||
in this file, C99 6.7.4p6. In GNU C89, a function declared
|
||||
'extern inline' is an external reference. */
|
||||
else if (declspecs->inline_p && storage_class != csc_static)
|
||||
DECL_EXTERNAL (decl) = (storage_class == csc_extern) == !flag_isoc99;
|
||||
else
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = !initialized;
|
||||
|
||||
/* Record absence of global scope for `static' or `auto'. */
|
||||
TREE_PUBLIC (decl)
|
||||
@ -4757,11 +4804,7 @@ grokdeclarator (const struct c_declarator *declarator,
|
||||
the abstract origin pointing between the declarations,
|
||||
which will confuse dwarf2out. */
|
||||
if (initialized)
|
||||
{
|
||||
DECL_INLINE (decl) = 1;
|
||||
if (storage_class == csc_extern)
|
||||
current_extern_inline = 1;
|
||||
}
|
||||
DECL_INLINE (decl) = 1;
|
||||
}
|
||||
/* If -finline-functions, assume it can be inlined. This does
|
||||
two things: let the function be deferred until it is actually
|
||||
@ -5259,12 +5302,15 @@ start_struct (enum tree_code code, tree name)
|
||||
error ("nested redefinition of %<union %E%>", name);
|
||||
else
|
||||
error ("nested redefinition of %<struct %E%>", name);
|
||||
/* Don't create structures that contain themselves. */
|
||||
ref = NULL_TREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise create a forward-reference just so the tag is in scope. */
|
||||
|
||||
/* Otherwise create a forward-reference just so the tag is in scope. */
|
||||
|
||||
if (ref == NULL_TREE || TREE_CODE (ref) != code)
|
||||
{
|
||||
ref = make_node (code);
|
||||
pushtag (name, ref);
|
||||
}
|
||||
@ -5956,7 +6002,6 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
|
||||
current_function_returns_null = 0;
|
||||
current_function_returns_abnormally = 0;
|
||||
warn_about_return_type = 0;
|
||||
current_extern_inline = 0;
|
||||
c_switch_stack = NULL;
|
||||
|
||||
nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
|
||||
@ -6108,12 +6153,6 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
|
||||
warning (OPT_Wmissing_declarations,
|
||||
"%q+D was used with no declaration before its definition", decl1);
|
||||
|
||||
/* This is a definition, not a reference.
|
||||
So normally clear DECL_EXTERNAL.
|
||||
However, `extern inline' acts like a declaration
|
||||
except for defining how to inline. So set DECL_EXTERNAL in that case. */
|
||||
DECL_EXTERNAL (decl1) = current_extern_inline;
|
||||
|
||||
/* This function exists in static storage.
|
||||
(This does not mean `static' in the C sense!) */
|
||||
TREE_STATIC (decl1) = 1;
|
||||
@ -6846,7 +6885,6 @@ c_push_function_context (struct function *f)
|
||||
p->returns_null = current_function_returns_null;
|
||||
p->returns_abnormally = current_function_returns_abnormally;
|
||||
p->warn_about_return_type = warn_about_return_type;
|
||||
p->extern_inline = current_extern_inline;
|
||||
}
|
||||
|
||||
/* Restore the variables used during compilation of a C function. */
|
||||
@ -6875,7 +6913,6 @@ c_pop_function_context (struct function *f)
|
||||
current_function_returns_null = p->returns_null;
|
||||
current_function_returns_abnormally = p->returns_abnormally;
|
||||
warn_about_return_type = p->warn_about_return_type;
|
||||
current_extern_inline = p->extern_inline;
|
||||
|
||||
f->language = NULL;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1,3 +1,18 @@
|
||||
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; }
|
||||
|
56
gcc/testsuite/gcc.dg/inline-13.c
Normal file
56
gcc/testsuite/gcc.dg/inline-13.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* 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);
|
23
gcc/testsuite/gcc.dg/inline-14.c
Normal file
23
gcc/testsuite/gcc.dg/inline-14.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* 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;
|
||||
}
|
7
gcc/testsuite/gcc.dg/inline-15.c
Normal file
7
gcc/testsuite/gcc.dg/inline-15.c
Normal file
@ -0,0 +1,7 @@
|
||||
/* 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" } */
|
21
gcc/testsuite/gcc.dg/inline-16.c
Normal file
21
gcc/testsuite/gcc.dg/inline-16.c
Normal file
@ -0,0 +1,21 @@
|
||||
/* { 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;
|
||||
}
|
14
gcc/testsuite/gcc.dg/inline6.c
Normal file
14
gcc/testsuite/gcc.dg/inline6.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* { 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++;
|
||||
}
|
9
gcc/testsuite/gcc.dg/inline7.c
Normal file
9
gcc/testsuite/gcc.dg/inline7.c
Normal file
@ -0,0 +1,9 @@
|
||||
/* { 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user