static bool cp_ubsan_instrument_vptr_p (tree type) { if (!flag_rtti || flag_sanitize_undefined_trap_on_error) return false; if (!do_ubsan_in_current_function ()) return false; if (type) { type = TYPE_MAIN_VARIANT (type); if (!CLASS_TYPE_P (type) || !CLASSTYPE_VTABLES (type)) return false; } return true; }
void i386_pe_adjust_class_at_definition (tree t) { tree member; gcc_assert (CLASS_TYPE_P (t)); /* We only look at dllimport. The only thing that dllexport does is add stuff to a '.drectiv' section at end-of-file, so no need to do anything for dllexport'd classes until we generate RTL. */ if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) == NULL_TREE) return; /* We don't actually add the attribute to the decl, just set the flag that signals that the address of this symbol is not a compile-time constant. Any subsequent out-of-class declaration of members wil cause the DECL_DLLIMPORT_P flag to be unset. (See tree.c: merge_dllimport_decl_attributes). That is just right since out-of class declarations can only be a definition. We recheck the class members at RTL generation to emit warnings if this has happened. Definition of static data member of dllimport'd class always causes an error (as per MS compiler). */ /* Check static VAR_DECL's. */ for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) if (TREE_CODE (member) == VAR_DECL) maybe_add_dllimport (member); /* Check FUNCTION_DECL's. */ for (member = TYPE_METHODS (t); member; member = TREE_CHAIN (member)) if (TREE_CODE (member) == FUNCTION_DECL) maybe_add_dllimport (member); /* Check vtables */ for (member = CLASSTYPE_VTABLES (t); member; member = TREE_CHAIN (member)) if (TREE_CODE (member) == VAR_DECL) maybe_add_dllimport (member); /* We leave typeinfo tables alone. We can't mark TI objects as dllimport, since the address of a secondary VTT may be needed for static initialization of a primary VTT. VTT's of dllimport'd classes should always be link-once COMDAT. */ }
static bool cp_ubsan_instrument_vptr_p (tree type) { if (!flag_rtti || flag_sanitize_undefined_trap_on_error) return false; if (current_function_decl && lookup_attribute ("no_sanitize_undefined", DECL_ATTRIBUTES (current_function_decl))) return false; if (type) { type = TYPE_MAIN_VARIANT (type); if (!CLASS_TYPE_P (type) || !CLASSTYPE_VTABLES (type)) return false; } return true; }
static bool cp_ubsan_instrument_vptr_p (tree type) { if (!flag_rtti || flag_sanitize_undefined_trap_on_error) return false; if (!sanitize_flags_p (SANITIZE_VPTR)) return false; if (current_function_decl == NULL_TREE) return false; if (type) { type = TYPE_MAIN_VARIANT (type); if (!CLASS_TYPE_P (type) || !CLASSTYPE_VTABLES (type)) return false; } return true; }
void i386_pe_adjust_class_at_definition (tree t) { tree member; gcc_assert (CLASS_TYPE_P (t)); if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (t)) != NULL_TREE) { tree tmv = TYPE_MAIN_VARIANT (t); /* Make sure that we set dllexport attribute to typeinfo's base declaration, as otherwise it would fail to be exported as it isn't a class-member. */ if (tmv != NULL_TREE && CLASSTYPE_TYPEINFO_VAR (tmv) != NULL_TREE) { tree na, ti_decl = CLASSTYPE_TYPEINFO_VAR (tmv); na = tree_cons (get_identifier ("dllexport"), NULL_TREE, NULL_TREE); decl_attributes (&ti_decl, na, 0); } /* Check static VAR_DECL's. */ for (member = TYPE_FIELDS (t); member; member = DECL_CHAIN (member)) if (TREE_CODE (member) == VAR_DECL) maybe_add_dllexport (member); /* Check FUNCTION_DECL's. */ for (member = TYPE_METHODS (t); member; member = DECL_CHAIN (member)) if (TREE_CODE (member) == FUNCTION_DECL) { tree thunk; maybe_add_dllexport (member); /* Also add the attribute to its thunks. */ for (thunk = DECL_THUNKS (member); thunk; thunk = TREE_CHAIN (thunk)) maybe_add_dllexport (thunk); } /* Check vtables */ for (member = CLASSTYPE_VTABLES (t); member; member = DECL_CHAIN (member)) if (TREE_CODE (member) == VAR_DECL) maybe_add_dllexport (member); } else if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) != NULL_TREE) { /* We don't actually add the attribute to the decl, just set the flag that signals that the address of this symbol is not a compile-time constant. Any subsequent out-of-class declaration of members wil cause the DECL_DLLIMPORT_P flag to be unset. (See tree.c: merge_dllimport_decl_attributes). That is just right since out-of class declarations can only be a definition. */ /* Check static VAR_DECL's. */ for (member = TYPE_FIELDS (t); member; member = DECL_CHAIN (member)) if (TREE_CODE (member) == VAR_DECL) maybe_add_dllimport (member); /* Check FUNCTION_DECL's. */ for (member = TYPE_METHODS (t); member; member = DECL_CHAIN (member)) if (TREE_CODE (member) == FUNCTION_DECL) { tree thunk; maybe_add_dllimport (member); /* Also add the attribute to its thunks. */ for (thunk = DECL_THUNKS (member); thunk; thunk = DECL_CHAIN (thunk)) maybe_add_dllimport (thunk); } /* Check vtables */ for (member = CLASSTYPE_VTABLES (t); member; member = DECL_CHAIN (member)) if (TREE_CODE (member) == VAR_DECL) maybe_add_dllimport (member); /* We leave typeinfo tables alone. We can't mark TI objects as dllimport, since the address of a secondary VTT may be needed for static initialization of a primary VTT. VTT's of dllimport'd classes should always be link-once COMDAT. */ } }