Commit da489f73 by Richard Henderson Committed by Richard Henderson

varasm.c (initializer_constant_valid_p): Don't deny DECL_DLLIMPORT_P on functions.

	* varasm.c (initializer_constant_valid_p): Don't deny
	DECL_DLLIMPORT_P on functions.

	* config/i386/cygming.h: Remove function declarations.
	(SUBTARGET_ENCODE_SECTION_INFO): Don't undef first.
	(ASM_OUTPUT_LABELREF): Remove.
	(COMMON_ASM_OP): Remove.
	(ASM_OUTPUT_COMMON): Remove.
	(ASM_OUTPUT_ALIGNED_DECL_COMMON): New.
	(ASM_DECLARE_OBJECT_NAME): Use i386_pe_maybe_record_exported_symbol.
	(ASM_DECLARE_FUNCTION_NAME): Likewise.
	* config/i386/i386-interix.h (SUBTARGET_ENCODE_SECTION_INFO):
	Rename from TARGET_ENCODE_SECTION_INFO.
	* config/i386/netware.h: Likewise.
	* config/i386/i386-protos.h: Update.
	* config/i386/i386.c (ix86_function_ok_for_sibcall): Turn ifdef
	of TARGET_DLLIMPORT_DECL_ATTRIBUTES into straight if.
	(legitimate_constant_p): Reject dllimports.
	(dllimport_map, get_dllimport_decl): New.
	(legitimize_dllimport_symbol): New.
	(legitimize_address, ix86_expand_move): Use it.
	(TARGET_BINDS_LOCAL_P): Redefine for TARGET_DLLIMPORT_DECL_ATTRIBUTES.
	* config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Remove.
	(SYMBOL_FLAG_DLLIMPORT, SYMBOL_REF_DLLIMPORT_P): New.
	(SYMBOL_FLAG_DLLEXPORT, SYMBOL_REF_DLLEXPORT_P): New.
	* config/i386/predicates.md (constant_call_address_operand): Only
	accept symbols; reject dllimport_p symbols.
	* config/i386/uwin.h (ASM_DECLARE_FUNCTION_NAME): Use
	i386_pe_maybe_record_exported_symbol.
	* config/i386/winnt.c (DLL_IMPORT_PREFIX, DLL_EXPORT_PREFIX): Remove.
	(i386_pe_determine_dllexport_p): Rename from i386_pe_dllexport_p.
	(i386_pe_determine_dllimport_p): Rename from i386_pe_dllimport_p;
	trust the setting of DECL_DLLIMPORT_P.
	(i386_pe_dllexport_name_p, i386_pe_dllimport_name_p): Remove.
	(i386_pe_mark_dllexport, i386_pe_mark_dllimport): Remove.
	(gen_stdcall_or_fastcall_suffix): Return NULL if no change required;
	tidy the argument scanning loop.
	(i386_pe_encode_section_info): Set SYMBOL_FLAG_DLLIMPORT and
	SYMBOL_FLAG_DLLEXPORT in SYMBOL_REF_FLAGS.
	(i386_pe_strip_name_encoding): Remove.
	(i386_pe_binds_local_p): New.
	(i386_pe_strip_name_encoding_full): Use default_strip_name_encoding.
	(i386_pe_output_labelref): Remove.
	(i386_pe_asm_output_aligned_decl_common): New.
	(i386_pe_maybe_record_exported_symbol): Rename from
	i386_pe_record_exported_symbol; check for dllexported symbols.

From-SVN: r123344
parent 0c9bce0b
2007-03-29 Richard Henderson <rth@redhat.com>
* varasm.c (initializer_constant_valid_p): Don't deny
DECL_DLLIMPORT_P on functions.
* config/i386/cygming.h: Remove function declarations.
(SUBTARGET_ENCODE_SECTION_INFO): Don't undef first.
(ASM_OUTPUT_LABELREF): Remove.
(COMMON_ASM_OP): Remove.
(ASM_OUTPUT_COMMON): Remove.
(ASM_OUTPUT_ALIGNED_DECL_COMMON): New.
(ASM_DECLARE_OBJECT_NAME): Use i386_pe_maybe_record_exported_symbol.
(ASM_DECLARE_FUNCTION_NAME): Likewise.
* config/i386/i386-interix.h (SUBTARGET_ENCODE_SECTION_INFO):
Rename from TARGET_ENCODE_SECTION_INFO.
* config/i386/netware.h: Likewise.
* config/i386/i386-protos.h: Update.
* config/i386/i386.c (ix86_function_ok_for_sibcall): Turn ifdef
of TARGET_DLLIMPORT_DECL_ATTRIBUTES into straight if.
(legitimate_constant_p): Reject dllimports.
(dllimport_map, get_dllimport_decl): New.
(legitimize_dllimport_symbol): New.
(legitimize_address, ix86_expand_move): Use it.
(TARGET_BINDS_LOCAL_P): Redefine for TARGET_DLLIMPORT_DECL_ATTRIBUTES.
* config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Remove.
(SYMBOL_FLAG_DLLIMPORT, SYMBOL_REF_DLLIMPORT_P): New.
(SYMBOL_FLAG_DLLEXPORT, SYMBOL_REF_DLLEXPORT_P): New.
* config/i386/predicates.md (constant_call_address_operand): Only
accept symbols; reject dllimport_p symbols.
* config/i386/uwin.h (ASM_DECLARE_FUNCTION_NAME): Use
i386_pe_maybe_record_exported_symbol.
* config/i386/winnt.c (DLL_IMPORT_PREFIX, DLL_EXPORT_PREFIX): Remove.
(i386_pe_determine_dllexport_p): Rename from i386_pe_dllexport_p.
(i386_pe_determine_dllimport_p): Rename from i386_pe_dllimport_p;
trust the setting of DECL_DLLIMPORT_P.
(i386_pe_dllexport_name_p, i386_pe_dllimport_name_p): Remove.
(i386_pe_mark_dllexport, i386_pe_mark_dllimport): Remove.
(gen_stdcall_or_fastcall_suffix): Return NULL if no change required;
tidy the argument scanning loop.
(i386_pe_encode_section_info): Set SYMBOL_FLAG_DLLIMPORT and
SYMBOL_FLAG_DLLEXPORT in SYMBOL_REF_FLAGS.
(i386_pe_strip_name_encoding): Remove.
(i386_pe_binds_local_p): New.
(i386_pe_strip_name_encoding_full): Use default_strip_name_encoding.
(i386_pe_output_labelref): Remove.
(i386_pe_asm_output_aligned_decl_common): New.
(i386_pe_maybe_record_exported_symbol): Rename from
i386_pe_record_exported_symbol; check for dllexported symbols.
2007-03-29 Zack Weinberg <zack@mrtock.ucsd.edu>
* gengtype.c (oprintf): Mostly revert changes from 2007-03-26;
......
......@@ -148,39 +148,20 @@ do { \
section and we need to set DECL_SECTION_NAME so we do that here.
Note that we can be called twice on the same decl. */
#undef SUBTARGET_ENCODE_SECTION_INFO
#define SUBTARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING i386_pe_strip_name_encoding_full
/* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF i386_pe_output_labelref
#undef COMMON_ASM_OP
#define COMMON_ASM_OP "\t.comm\t"
/* Output a common block. */
#undef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME, 1); \
if (! i386_pe_dllimport_name_p (NAME)) \
{ \
fprintf ((STREAM), "\t.comm\t"); \
assemble_name ((STREAM), (NAME)); \
fprintf ((STREAM), ", %d\t%s %d\n", \
(int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)); \
} \
} while (0)
#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
#define ASM_OUTPUT_ALIGNED_DECL_COMMON \
i386_pe_asm_output_aligned_decl_common
/* Output the label for an initialized variable. */
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME, 1); \
i386_pe_maybe_record_exported_symbol (DECL, NAME, 1); \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} while (0)
......@@ -210,7 +191,6 @@ do { \
/* Windows uses explicit import from shared libraries. */
#define MULTIPLE_SYMBOL_SPACES 1
extern void i386_pe_unique_section (TREE, int);
#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
......@@ -229,8 +209,7 @@ extern void i386_pe_unique_section (TREE, int);
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do \
{ \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME, 0); \
i386_pe_maybe_record_exported_symbol (DECL, NAME, 0); \
if (write_symbols != SDB_DEBUG) \
i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
ASM_OUTPUT_LABEL (FILE, NAME); \
......@@ -289,15 +268,6 @@ extern void i386_pe_unique_section (TREE, int);
build_tree_list (get_identifier ("stdcall"), \
NULL))
/* External function declarations. */
extern void i386_pe_record_external_function (tree, const char *);
extern void i386_pe_declare_function_type (FILE *, const char *, int);
extern void i386_pe_record_exported_symbol (const char *, int);
extern void i386_pe_file_end (void);
extern int i386_pe_dllexport_name_p (const char *);
extern int i386_pe_dllimport_name_p (const char *);
/* For Win32 ABI compatibility */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0
......@@ -315,10 +285,10 @@ extern int i386_pe_dllimport_name_p (const char *);
machine. Use this macro to limit the alignment which can be
specified using the `__attribute__ ((aligned (N)))' construct. If
not defined, the default value is `BIGGEST_ALIGNMENT'. */
#undef MAX_OFILE_ALIGNMENT
/* IMAGE_SCN_ALIGN_8192BYTES is the largest section alignment flag
specified in the PECOFF60 spec. Native MS compiler also limits
user-specified alignment to 8192 bytes. */
#undef MAX_OFILE_ALIGNMENT
#define MAX_OFILE_ALIGNMENT (8192 * 8)
/* Native complier aligns internal doubles in structures on dword boundaries. */
......@@ -334,6 +304,7 @@ extern int i386_pe_dllimport_name_p (const char *);
#ifndef SET_ASM_OP
#define SET_ASM_OP "\t.set\t"
#endif
/* This implements the `alias' attribute, keeping any stdcall or
fastcall decoration. */
#undef ASM_OUTPUT_DEF_FROM_DECLS
......
......@@ -326,8 +326,7 @@ while (0)
differently depending on something about the variable or
function named by the symbol (such as what section it is in). */
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
#define SUBTARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING i386_pe_strip_name_encoding_full
......
......@@ -191,9 +191,6 @@ extern int ix86_local_alignment (tree, int);
extern int ix86_constant_alignment (tree, int);
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
extern int x86_field_alignment (tree, int);
#endif
......@@ -206,18 +203,22 @@ extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
extern void ix86_expand_reduc_v4sf (rtx (*)(rtx, rtx, rtx), rtx, rtx);
/* In winnt.c */
extern int i386_pe_dllexport_name_p (const char *);
extern int i386_pe_dllimport_name_p (const char *);
extern void i386_pe_unique_section (tree, int);
extern void i386_pe_declare_function_type (FILE *, const char *, int);
extern void i386_pe_record_external_function (tree, const char *);
extern void i386_pe_record_exported_symbol (const char *, int);
extern void i386_pe_maybe_record_exported_symbol (tree, const char *, int);
extern void i386_pe_asm_file_end (FILE *);
extern void i386_pe_encode_section_info (tree, rtx, int);
extern const char *i386_pe_strip_name_encoding (const char *);
extern bool i386_pe_binds_local_p (tree);
extern const char *i386_pe_strip_name_encoding_full (const char *);
extern void i386_pe_output_labelref (FILE *, const char *);
extern bool i386_pe_valid_dllimport_attribute_p (tree);
extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
extern void i386_pe_asm_output_aligned_decl_common (FILE *, tree,
const char *,
HOST_WIDE_INT,
HOST_WIDE_INT);
extern void i386_pe_file_end (void);
/* In winnt-cxx.c and winnt-stubs.c */
extern void i386_pe_adjust_class_at_definition (tree);
......
......@@ -2569,12 +2569,11 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
}
}
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
/* Dllimport'd functions are also called indirectly. */
if (decl && DECL_DLLIMPORT_P (decl)
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& decl && DECL_DLLIMPORT_P (decl)
&& ix86_function_regparm (TREE_TYPE (decl), NULL) >= 3)
return false;
#endif
/* If we forced aligned the stack, then sibcalling would unalign the
stack, which may break the called function. */
......@@ -6332,6 +6331,11 @@ legitimate_constant_p (rtx x)
/* TLS symbols are never valid. */
if (SYMBOL_REF_TLS_MODEL (x))
return false;
/* DLLIMPORT symbols are never valid. */
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& SYMBOL_REF_DLLIMPORT_P (x))
return false;
break;
case CONST_DOUBLE:
......@@ -7189,6 +7193,90 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
return dest;
}
/* Create or return the unique __imp_DECL dllimport symbol corresponding
to symbol DECL. */
static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
htab_t dllimport_map;
static tree
get_dllimport_decl (tree decl)
{
struct tree_map *h, in;
void **loc;
const char *name;
const char *prefix;
size_t namelen, prefixlen;
char *imp_name;
tree to;
rtx rtl;
if (!dllimport_map)
dllimport_map = htab_create_ggc (512, tree_map_hash, tree_map_eq, 0);
in.hash = htab_hash_pointer (decl);
in.base.from = decl;
loc = htab_find_slot_with_hash (dllimport_map, &in, in.hash, INSERT);
h = *loc;
if (h)
return h->to;
*loc = h = ggc_alloc (sizeof (struct tree_map));
h->hash = in.hash;
h->base.from = decl;
h->to = to = build_decl (VAR_DECL, NULL, ptr_type_node);
DECL_ARTIFICIAL (to) = 1;
DECL_IGNORED_P (to) = 1;
DECL_EXTERNAL (to) = 1;
TREE_READONLY (to) = 1;
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
name = targetm.strip_name_encoding (name);
if (name[0] == FASTCALL_PREFIX)
{
name++;
prefix = "*__imp_";
}
else
prefix = "*__imp__";
namelen = strlen (name);
prefixlen = strlen (prefix);
imp_name = alloca (namelen + prefixlen + 1);
memcpy (imp_name, prefix, prefixlen);
memcpy (imp_name + prefixlen, name, namelen + 1);
name = ggc_alloc_string (imp_name, namelen + prefixlen);
rtl = gen_rtx_SYMBOL_REF (Pmode, name);
SET_SYMBOL_REF_DECL (rtl, to);
SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL;
rtl = gen_const_mem (Pmode, rtl);
set_mem_alias_set (rtl, ix86_GOT_alias_set ());
SET_DECL_RTL (to, rtl);
return to;
}
/* Expand SYMBOL into its corresponding dllimport symbol. WANT_REG is
true if we require the result be a register. */
static rtx
legitimize_dllimport_symbol (rtx symbol, bool want_reg)
{
tree imp_decl;
rtx x;
gcc_assert (SYMBOL_REF_DECL (symbol));
imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol));
x = DECL_RTL (imp_decl);
if (want_reg)
x = force_reg (Pmode, x);
return x;
}
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This macro is used in only one place: `memory_address' in explow.c.
......@@ -7231,6 +7319,20 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
if (flag_pic && SYMBOLIC_CONST (x))
return legitimize_pic_address (x, 0);
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
{
if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (x))
return legitimize_dllimport_symbol (x, true);
if (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
&& SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (x, 0), 0)))
{
rtx t = legitimize_dllimport_symbol (XEXP (XEXP (x, 0), 0), true);
return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
}
}
/* Canonicalize shifts by 0, 1, 2, 3 into multiply */
if (GET_CODE (x) == ASHIFT
&& CONST_INT_P (XEXP (x, 1))
......@@ -9236,20 +9338,31 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
if (op1 == op0)
return;
}
else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& SYMBOL_REF_DLLIMPORT_P (op1))
op1 = legitimize_dllimport_symbol (op1, false);
}
else if (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF)
{
model = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (op1, 0), 0));
rtx addend = XEXP (XEXP (op1, 0), 1);
rtx symbol = XEXP (XEXP (op1, 0), 0);
rtx tmp = NULL;
model = SYMBOL_REF_TLS_MODEL (symbol);
if (model)
tmp = legitimize_tls_address (symbol, model, true);
else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& SYMBOL_REF_DLLIMPORT_P (symbol))
tmp = legitimize_dllimport_symbol (symbol, true);
if (tmp)
{
rtx addend = XEXP (XEXP (op1, 0), 1);
op1 = legitimize_tls_address (XEXP (XEXP (op1, 0), 0), model, true);
op1 = force_operand (op1, NULL);
op1 = expand_simple_binop (Pmode, PLUS, op1, addend,
tmp = force_operand (tmp, NULL);
tmp = expand_simple_binop (Pmode, PLUS, tmp, addend,
op0, 1, OPTAB_DIRECT);
if (op1 == op0)
if (tmp == op0)
return;
}
}
......@@ -21648,6 +21761,10 @@ static const struct attribute_spec ix86_attribute_table[] =
#undef TARGET_BINDS_LOCAL_P
#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
#endif
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
#undef TARGET_BINDS_LOCAL_P
#define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
#endif
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
......
......@@ -2347,8 +2347,6 @@ enum ix86_stack_slot
(! IN_RANGE ((SRC), FIRST_STACK_REG, LAST_STACK_REG))
#define DLL_IMPORT_EXPORT_PREFIX '#'
#define FASTCALL_PREFIX '@'
struct machine_function GTY(())
......@@ -2398,6 +2396,17 @@ struct machine_function GTY(())
#define SYMBOL_FLAG_FAR_ADDR (SYMBOL_FLAG_MACH_DEP << 0)
#define SYMBOL_REF_FAR_ADDR_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_FAR_ADDR) != 0)
/* Flags to mark dllimport/dllexport. Used by PE ports, but handy to
have defined always, to avoid ifdefing. */
#define SYMBOL_FLAG_DLLIMPORT (SYMBOL_FLAG_MACH_DEP << 1)
#define SYMBOL_REF_DLLIMPORT_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLIMPORT) != 0)
#define SYMBOL_FLAG_DLLEXPORT (SYMBOL_FLAG_MACH_DEP << 2)
#define SYMBOL_REF_DLLEXPORT_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLEXPORT) != 0)
/*
Local variables:
version-control: t
......
......@@ -150,7 +150,6 @@ Boston, MA 02110-1301, USA. */
the number of registers used, and an atsign (@). */
void i386_nlm_encode_section_info (tree, rtx, int);
const char *i386_nlm_strip_name_encoding (const char *);
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO i386_nlm_encode_section_info
#define SUBTARGET_ENCODE_SECTION_INFO i386_nlm_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING i386_nlm_strip_name_encoding
......@@ -484,9 +484,14 @@
;; Test for a pc-relative call operand
(define_predicate "constant_call_address_operand"
(and (ior (match_code "symbol_ref")
(match_operand 0 "local_symbolic_operand"))
(match_test "ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC")))
(match_code "symbol_ref")
{
if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
return false;
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op))
return false;
return true;
})
;; True for any non-virtual or eliminable register. Used in places where
;; instantiation of such a register may cause the pattern to not be recognized.
......
......@@ -77,8 +77,7 @@ Boston, MA 02110-1301, USA. */
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do \
{ \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME, 0); \
i386_pe_maybe_record_exported_symbol (DECL, NAME, 0); \
/* UWIN binutils bug workaround. */ \
if (0 && write_symbols != SDB_DEBUG) \
i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
......
......@@ -4063,9 +4063,8 @@ initializer_constant_valid_p (tree value, tree endtype)
return null_pointer_node;
/* Taking the address of a nested function involves a trampoline. */
if (TREE_CODE (value) == FUNCTION_DECL
&& ((decl_function_context (value)
&& !DECL_NO_STATIC_CHAIN (value))
|| DECL_DLLIMPORT_P (value)))
&& decl_function_context (value)
&& !DECL_NO_STATIC_CHAIN (value))
return NULL_TREE;
/* "&{...}" requires a temporary to hold the constructed
object. */
......
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