olddecl);
}
}
-
- if (DECL_DECLARED_INLINE_P (newdecl)
- && ! DECL_DECLARED_INLINE_P (olddecl)
- && TREE_ADDRESSABLE (olddecl) && warn_inline)
- {
- warning (0, "%q#D was used before it was declared inline", newdecl);
- warning (0, "%Jprevious non-inline declaration here", olddecl);
- }
}
}
warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
}
+
+ if (DECL_DELETED_FN (newdecl))
+ {
+ error ("deleted definition of %qD", newdecl);
+ error ("after previous declaration %q+D", olddecl);
+ }
}
/* Deal with C++: must preserve virtual function table size. */
&& DECL_INITIAL (new_result))
{
if (DECL_INITIAL (old_result))
- {
- DECL_INLINE (old_result) = 0;
- DECL_UNINLINABLE (old_result) = 1;
- }
+ DECL_UNINLINABLE (old_result) = 1;
else
- {
- DECL_INLINE (old_result) = DECL_INLINE (new_result);
- DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
- }
+ DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result);
DECL_NOT_REALLY_EXTERN (old_result)
= DECL_NOT_REALLY_EXTERN (new_result);
}
else
{
- DECL_INLINE (old_result)
- |= DECL_INLINE (new_result);
DECL_DECLARED_INLINE_P (old_result)
|= DECL_DECLARED_INLINE_P (new_result);
DECL_DISREGARD_INLINE_LIMITS (old_result)
}
else if (new_defines_function && DECL_INITIAL (olddecl))
{
- /* C++ is always in in unit-at-a-time mode, so we never
- inline re-defined extern inline functions. */
- DECL_INLINE (newdecl) = 0;
+ /* Never inline re-defined extern inline functions.
+ FIXME: this could be better handled by keeping both
+ function as separate declarations. */
DECL_UNINLINABLE (newdecl) = 1;
}
else
DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
- /* If either decl says `inline', this fn is inline, unless
- its definition was passed already. */
- if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE)
- DECL_INLINE (olddecl) = 1;
- DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
-
DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
= (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
ggc_free (DECL_LANG_SPECIFIC (olddecl));
}
+ /* Merge the USED information. */
+ if (TREE_USED (olddecl))
+ TREE_USED (newdecl) = 1;
+ else if (TREE_USED (newdecl))
+ TREE_USED (olddecl) = 1;
+
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
int function_size;
We assume that such functions never throw; if this is incorrect,
callers should unset TREE_NOTHROW. */
-tree
+static tree
build_library_fn (tree name, tree type)
{
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
}
/* Like build_library_fn, but also pushes the function so that we will
- be able to find it via IDENTIFIER_GLOBAL_VALUE. */
+ be able to find it via IDENTIFIER_GLOBAL_VALUE. Also, the function
+ may throw exceptions listed in RAISES. */
tree
-push_library_fn (tree name, tree type)
+push_library_fn (tree name, tree type, tree raises)
{
- tree fn = build_library_fn (name, type);
+ tree fn;
+
+ if (raises)
+ type = build_exception_variant (type, raises);
+
+ fn = build_library_fn (name, type);
pushdecl_top_level (fn);
return fn;
}
push_void_library_fn (tree name, tree parmtypes)
{
tree type = build_function_type (void_type_node, parmtypes);
- return push_library_fn (name, type);
+ return push_library_fn (name, type, NULL_TREE);
}
/* Like push_library_fn, but also note that this function throws
tree
push_throw_library_fn (tree name, tree type)
{
- tree fn = push_library_fn (name, type);
+ tree fn = push_library_fn (name, type, NULL_TREE);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
/* Anonymous unions are objects, so they can have specifiers. */;
SET_ANON_AGGR_TYPE_P (declared_type);
- if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
- && !in_system_header)
- pedwarn ("ISO C++ prohibits anonymous structs");
+ if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header)
+ pedwarn (OPT_pedantic, "ISO C++ prohibits anonymous structs");
}
else
grokfield.) The DECL corresponding to the DECLARATOR is returned.
If an error occurs, the error_mark_node is returned instead.
- DECLSPECS are the decl-specifiers for the declaration. INITIALIZED
- is true if an explicit initializer is present, but false if this is
- a variable implicitly initialized via a default constructor.
- ATTRIBUTES and PREFIX_ATTRIBUTES are GNU attributes associated with
- this declaration. *PUSHED_SCOPE_P is set to the scope entered in
- this function, if any; if set, the caller is responsible for
- calling pop_scope. */
+ DECLSPECS are the decl-specifiers for the declaration. INITIALIZED is 1
+ if an explicit initializer is present, or 2 for an explicitly defaulted
+ function, or 3 for an explicitly deleted function, but 0 if this is a
+ variable implicitly initialized via a default constructor. ATTRIBUTES
+ and PREFIX_ATTRIBUTES are GNU attributes associated with this
+ declaration. *PUSHED_SCOPE_P is set to the scope entered in this
+ function, if any; if set, the caller is responsible for calling
+ pop_scope. */
tree
start_decl (const cp_declarator *declarator,
switch (TREE_CODE (decl))
{
case TYPE_DECL:
- error ("typedef %qD is initialized (use __typeof__ instead)", decl);
+ error ("typedef %qD is initialized (use decltype instead)", decl);
return error_mark_node;
case FUNCTION_DECL:
- error ("function %q#D is initialized like a variable", decl);
- return error_mark_node;
+ if (initialized == 3)
+ /* We'll handle the rest of the semantics later, but we need to
+ set this now so it's visible to duplicate_decls. */
+ DECL_DELETED_FN (decl) = 1;
+ break;
default:
break;
if (!CP_AGGREGATE_TYPE_P (type))
{
/* It is invalid to initialize a non-aggregate type with a
- brace-enclosed initializer.
+ brace-enclosed initializer before C++0x.
We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
a CONSTRUCTOR (with a record type). */
if (TREE_CODE (init) == CONSTRUCTOR
&& BRACE_ENCLOSED_INITIALIZER_P (init)) /* p7626.C */
{
- error ("braces around scalar initializer for type %qT", type);
- init = error_mark_node;
+ if (SCALAR_TYPE_P (type))
+ {
+ error ("braces around scalar initializer for type %qT", type);
+ init = error_mark_node;
+ }
+ else
+ maybe_warn_cpp0x ("extended initializer lists");
}
d->cur++;
else
abstract_virtuals_error (decl, type);
- if (TREE_CODE (decl) == FUNCTION_DECL
- || TREE_TYPE (decl) == error_mark_node)
+ if (TREE_TYPE (decl) == error_mark_node)
/* No initialization required. */
;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (init)
+ {
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ /* fixme check this is 1st decl */
+ DECL_DELETED_FN (decl) = 1;
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (!defaultable_fn_p (decl))
+ error ("%qD cannot be defaulted", decl);
+ else
+ {
+ /* An out-of-class default definition is defined at
+ the point where it is explicitly defaulted. */
+ DECL_DEFAULTED_FN (decl) = 1;
+ if (DECL_INITIAL (decl) == error_mark_node)
+ synthesize_method (decl);
+ }
+ }
+ else
+ error ("function %q#D is initialized like a variable", decl);
+ }
+ /* else no initialization required. */
+ }
else if (DECL_EXTERNAL (decl)
&& ! (DECL_LANG_SPECIFIC (decl)
&& DECL_NOT_REALLY_EXTERN (decl)))
actually needed. It is unlikely that it will be inlined, since
it is only called via a function pointer, but we avoid unnecessary
emissions this way. */
- DECL_INLINE (fndecl) = 1;
- DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_INTERFACE_KNOWN (fndecl) = 1;
/* Build the parameter. */
if (use_cxa_atexit)
void_list_node);
tree vfntype = build_function_type (void_type_node, argtypes);
acquire_fn = push_library_fn
- (acquire_fn, build_function_type (integer_type_node, argtypes));
- release_fn = push_library_fn (release_fn, vfntype);
- abort_fn = push_library_fn (abort_fn, vfntype);
+ (acquire_fn, build_function_type (integer_type_node, argtypes),
+ NULL_TREE);
+ release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
+ abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
}
else
{
/* If the declaration was declared inline, mark it as such. */
if (inlinep)
DECL_DECLARED_INLINE_P (decl) = 1;
- /* We inline functions that are explicitly declared inline, or, when
- the user explicitly asks us to, all functions. */
- if (DECL_DECLARED_INLINE_P (decl)
- || (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag))
- DECL_INLINE (decl) = 1;
DECL_EXTERNAL (decl) = 1;
if (quals && TREE_CODE (type) == FUNCTION_TYPE)
newtype = build_function_type (integer_type_node, oldtypeargs);
TREE_TYPE (decl) = newtype;
}
- check_main_parameter_types (decl);
+ if (warn_main)
+ check_main_parameter_types (decl);
}
if (ctype != NULL_TREE
TYPE_MAIN_VARIANT (t) = unqualified_variant;
TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
TYPE_NEXT_VARIANT (unqualified_variant) = t;
+ TREE_TYPE (TYPE_BINFO (t)) = t;
}
/* Cache this pointer-to-member type so that we can find it again
later. */
TYPE_SET_PTRMEMFUNC_TYPE (type, t);
- /* Managing canonical types for the RECORD_TYPE behind a
- pointer-to-member function is a nightmare, so use structural
- equality for now. */
- SET_TYPE_STRUCTURAL_EQUALITY (t);
+ if (TYPE_STRUCTURAL_EQUALITY_P (type))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (type) != type)
+ TYPE_CANONICAL (t) = build_ptrmemfunc_type (TYPE_CANONICAL (type));
return t;
}
error ("ISO C++ forbids in-class initialization of non-const "
"static member %qD",
decl);
- else if (pedantic && !INTEGRAL_TYPE_P (type))
- pedwarn ("ISO C++ forbids initialization of member constant "
+ else if (!INTEGRAL_TYPE_P (type))
+ pedwarn (OPT_pedantic, "ISO C++ forbids initialization of member constant "
"%qD of non-integral type %qT", decl, type);
return 0;
}
/* As an extension we allow zero-sized arrays. We always allow
them in system headers because glibc uses them. */
- else if (integer_zerop (size) && pedantic && !in_system_header)
+ else if (integer_zerop (size) && !in_system_header)
{
if (name)
- pedwarn ("ISO C++ forbids zero-size array %qD", name);
+ pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
else
- pedwarn ("ISO C++ forbids zero-size array");
+ pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array");
}
}
else if (TREE_CONSTANT (size))
else if (pedantic && warn_vla != 0)
{
if (name)
- pedwarn ("ISO C++ forbids variable length array %qD", name);
+ pedwarn (OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
else
- pedwarn ("ISO C++ forbids variable length array");
+ pedwarn (OPT_Wvla, "ISO C++ forbids variable length array");
}
else if (warn_vla > 0)
{
Don't make a DECL node; just return the ..._TYPE node.
FIELD for a struct or union field; make a FIELD_DECL.
BITFIELD for a field with specified width.
- INITIALIZED is 1 if the decl has an initializer.
+ INITIALIZED is as for start_decl.
ATTRLIST is a pointer to the list of attributes, which may be NULL
if there are none; *ATTRLIST may be modified if attributes from inside
else if (decl_context == BITFIELD)
bitfield = 1, decl_context = FIELD;
+ if (initialized > 1)
+ funcdef_flag = true;
+
/* Look inside a declarator for the name being declared
and get it as a string, for an error message. */
for (id_declarator = declarator;
else if (! is_main)
permerror ("ISO C++ forbids declaration of %qs with no type", name);
else if (pedantic)
- pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids declaration of %qs with no type", name);
else
warning (OPT_Wreturn_type,
"ISO C++ forbids declaration of %qs with no type", name);
ok = 1;
if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
{
- pedwarn ("long, short, signed or unsigned used invalidly for %qs",
+ pedwarn (OPT_pedantic,
+ "long, short, signed or unsigned used invalidly for %qs",
name);
if (flag_pedantic_errors)
ok = 0;
if (pedantic)
{
tree bad_type = build_qualified_type (type, type_quals);
- pedwarn ("ignoring %qV qualifiers added to function type %qT",
+ pedwarn (OPT_pedantic,
+ "ignoring %qV qualifiers added to function type %qT",
bad_type, type);
}
type_quals = TYPE_UNQUALIFIED;
friendp = 0;
}
else
- permerror ("extra qualification %<%T::%> on member %qs",
- ctype, name);
+ permerror_at (declarator->id_loc,
+ "extra qualification %<%T::%> on member %qs",
+ ctype, name);
}
else if (/* If the qualifying type is already complete, then we
can skip the following checks. */
&& pedantic)
{
if (storage_class == sc_static)
- pedwarn ("%<static%> specified invalid for function %qs "
+ pedwarn (OPT_pedantic,
+ "%<static%> specified invalid for function %qs "
"declared out of global scope", name);
else
- pedwarn ("%<inline%> specifier invalid for function %qs "
+ pedwarn (OPT_pedantic,
+ "%<inline%> specifier invalid for function %qs "
"declared out of global scope", name);
}
}
if (storage_class == sc_extern && pedantic)
{
- pedwarn ("cannot explicitly declare member %q#D to have "
- "extern linkage",
- decl);
+ pedwarn (OPT_pedantic,
+ "cannot explicitly declare member %q#D to have "
+ "extern linkage", decl);
storage_class = sc_none;
}
}
warning (0, "%qs initialized and declared %<extern%>", name);
}
else
- error ("%qs has both %<extern%> and initializer", name);
+ {
+ error ("%qs has both %<extern%> and initializer", name);
+ return error_mark_node;
+ }
}
/* Record `register' declaration for warnings on &
are no other parameters or else all other parameters have
default arguments. */
TYPE_HAS_INIT_REF (class_type) = 1;
+ if (!DECL_DEFAULTED_FN (decl))
+ TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
if (ctor > 1)
TYPE_HAS_CONST_INIT_REF (class_type) = 1;
}
if (assop)
{
TYPE_HAS_ASSIGN_REF (class_type) = 1;
+ if (!DECL_DEFAULTED_FN (decl))
+ TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
if (assop != 1)
TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
}
if (operator_code == POSTINCREMENT_EXPR
|| operator_code == POSTDECREMENT_EXPR)
{
- if (pedantic)
- pedwarn ("%qD cannot have default arguments", decl);
+ pedwarn (OPT_pedantic, "%qD cannot have default arguments",
+ decl);
}
else
{
basetype = PACK_EXPANSION_PATTERN (basetype);
if (TREE_CODE (basetype) == TYPE_DECL)
basetype = TREE_TYPE (basetype);
- if (TREE_CODE (basetype) != RECORD_TYPE
- && TREE_CODE (basetype) != TYPENAME_TYPE
- && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
- && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM)
+ if (!MAYBE_CLASS_TYPE_P (basetype) || TREE_CODE (basetype) == UNION_TYPE)
{
error ("base type %qT fails to be a struct or class type",
basetype);
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
&& !DECL_NAME (DECL_RESULT (fndecl))
- /* Normally, with -Wreturn-type, flow will complain. Unless we're an
- inline function, as we might never be compiled separately. */
- && (DECL_INLINE (fndecl) || processing_template_decl)
+ && !TREE_NO_WARNING (fndecl)
/* Structor return values (if any) are set by the compiler. */
&& !DECL_CONSTRUCTOR_P (fndecl)
&& !DECL_DESTRUCTOR_P (fndecl))
- warning (OPT_Wreturn_type, "no return statement in function returning non-void");
+ {
+ warning (OPT_Wreturn_type,
+ "no return statement in function returning non-void");
+ TREE_NO_WARNING (fndecl) = 1;
+ }
/* Store the end of the function, so that we get good line number
info for the epilogue. */
f->extern_decl_map = NULL;
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
- c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+ c_warn_unused_result (gimple_body (fndecl));
}
/* Clear out the bits we don't need. */
local_names = NULL;
check_template_shadow (fndecl);
DECL_DECLARED_INLINE_P (fndecl) = 1;
- if (flag_default_inline)
- DECL_INLINE (fndecl) = 1;
/* We process method specializations in finish_struct_1. */
if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))