Author: johannes Date: Sun Feb 3 15:49:58 2008 New Revision: 46690 URL: http://llvm.org/viewvc/llvm-project?rev=46690&view=rev Log: Fix dumb bug in virtual base class conversion: when a type is used as a vbc, then used as a type for an ordinary field, it can be "restored" even though it wasn't replaced originally, causing havoc later. Use a marker bit instead of repeating the logic.
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp llvm-gcc-4.2/trunk/gcc/tree.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=46690&r1=46689&r2=46690&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sun Feb 3 15:49:58 2008 @@ -232,6 +232,10 @@ // type should be passed in by invisible reference. // bool isPassedByInvisibleReference(tree Type) { + // Don't crash in this case. + if (Type == error_mark_node) + return false; + // FIXME: Search for TREE_ADDRESSABLE in calls.c, and see if there are other // cases that make arguments automatically passed in by reference. return TREE_ADDRESSABLE(Type) || TYPE_SIZE(Type) == 0 || @@ -1655,6 +1659,7 @@ TYPE_SIZE(newTy) = DECL_SIZE(Field); TYPE_SIZE_UNIT(newTy) = DECL_SIZE_UNIT(Field); TYPE_MAIN_VARIANT(newTy) = newTy; + TYPE_STUB_DECL(newTy) = TYPE_STUB_DECL(oldTy); // Change the name. if (TYPE_NAME(oldTy)) { const char *p = "anon"; @@ -1697,8 +1702,10 @@ TREE_CODE(DECL_SIZE(Field))==INTEGER_CST && TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST && TREE_INT_CST_LOW(DECL_SIZE(Field)) < - TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) + TREE_INT_CST_LOW(TYPE_SIZE(TREE_TYPE(Field)))) { TREE_TYPE(Field) = FixBaseClassField(Field); + DECL_FIELD_REPLACED(Field) = 1; + } } // Size of the complete type will be a multiple of its alignment. // In some cases involving empty C++ classes this is not true coming in. @@ -1734,23 +1741,16 @@ static void RestoreBaseClassFields(tree type) { assert(TREE_CODE(type)==RECORD_TYPE); for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) { - if (TREE_CODE(Field)==FIELD_DECL && - !DECL_BIT_FIELD_TYPE(Field) && - TREE_CODE(DECL_FIELD_OFFSET(Field))==INTEGER_CST && - TREE_CODE(TREE_TYPE(Field))==RECORD_TYPE && - TYPE_SIZE(TREE_TYPE(Field)) && - DECL_SIZE(Field) && - TREE_CODE(DECL_SIZE(Field))==INTEGER_CST && - TREE_CODE(TYPE_SIZE(TREE_TYPE(Field)))==INTEGER_CST) { + if (TREE_CODE(Field) == FIELD_DECL && DECL_FIELD_REPLACED(Field)) { tree &oldTy = BaseTypesMap[TREE_TYPE(Field)]; - if (oldTy) - TREE_TYPE(Field) = oldTy; + assert(oldTy); + TREE_TYPE(Field) = oldTy; + DECL_FIELD_REPLACED(Field) = 0; } } } - /// DecodeStructFields - This method decodes the specified field, if it is a /// FIELD_DECL, adding or updating the specified StructTypeConversionInfo to /// reflect it. Return tree if field is decoded correctly. Otherwise return Modified: llvm-gcc-4.2/trunk/gcc/tree.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.h?rev=46690&r1=46689&r2=46690&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree.h (original) +++ llvm-gcc-4.2/trunk/gcc/tree.h Sun Feb 3 15:49:58 2008 @@ -2724,6 +2724,11 @@ writing debugging information about vfield and vbase decls for C++. */ #define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.fcontext) +/* LLVM LOCAL begin */ +/* In a FIELD_DECL, marks that the type is temporarily replaced in ConvertType. */ +#define DECL_FIELD_REPLACED(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_0) +/* LLVM LOCAL end */ + /* In a FIELD_DECL, indicates this field should be bit-packed. */ #define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_1) _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits