This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR middle-end/30017 (ICE in C++ size hook)


Hi,
the attached testcase hits sanity check in C++ frontend after converting:
            __builtin_memcpy(this,&f,sizeof(FIND_RESULT));
to an assignment.  The hook cp_expr_size is called when expanding this
assignment resulting in ICE.  I think the check is just too strict
and can safely be dropped (as it also mentions that assignment is OK).

I wonder why we still need expr_size hook that late in gimple form?
The builtins.c code is using TYPE_SIZE_UNIT and those values are supposed to be in sync
(as otehrwise the conversion to = would end up in differently sized block copied).
What is difference in between those two at this stage?

I am bootstrapping/regtesting the patch on i686 but it will very likely to pass as there is nothing chnaged
except for the sanity check. Does this look OK?

class NAMES_ITEM { };
struct ATOM {
    const NAMES_ITEM& getPredItem() const { }
};
class ATOMSET {
public:
    class FIND_RESULT {
        const NAMES_ITEM &pattern;
    public:
        FIND_RESULT() : pattern(pattern)  { }
        FIND_RESULT(const FIND_RESULT &f) : pattern(f.pattern) { }
        FIND_RESULT(const NAMES_ITEM &pattern2) : pattern(pattern2) { }
void operator=(const FIND_RESULT &f)
        {
            __builtin_memcpy(this,&f,sizeof(FIND_RESULT));
        }
    };
    void find(const ATOM &pattern, FIND_RESULT &f) {
        FIND_RESULT result(pattern.getPredItem());
        f = result;
    }
};
class INTERPRET {
    ATOMSET positive;
public:
    void findInPositivePart(const ATOM &pattern, ATOMSET::FIND_RESULT &f)
    {
        positive.find(pattern,f);
    }
};
struct GINTERPRET {
    void isTrue (void);
};
extern INTERPRET J;
static GINTERPRET *I;
void printQueryI() {
    ATOM pattern;
    ATOMSET::FIND_RESULT f;
    J.findInPositivePart(pattern,f);
    I->isTrue();
}
	middle-end/30017
	* cp-objcp-common.c (cp_expr_size): Do not sanity check that
	size of certain classes does not matter.
Index: cp/cp-objcp-common.c
===================================================================
*** cp/cp-objcp-common.c        (revision 119360)
--- cp/cp-objcp-common.c        (working copy)
*************** cp_expr_size (tree exp)
*** 79,105 ****

    if (CLASS_TYPE_P (type))
      {
-       /* The backend should not be interested in the size of an expression
-        of a type with both of these set; all copies of such types must go
-        through a constructor or assignment op.  */
-       gcc_assert (!TYPE_HAS_COMPLEX_INIT_REF (type)
-                 || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)
-                 /* But storing a CONSTRUCTOR isn't a copy.  */
-                 || TREE_CODE (exp) == CONSTRUCTOR
-                 /* And, the gimplifier will sometimes make a copy of
-                    an aggregate.  In particular, for a case like:
- 
-                       struct S { S(); };
-                       struct X { int a; S s; };
-                       X x = { 0 };
- 
-                    the gimplifier will create a temporary with
-                    static storage duration, perform static
-                    initialization of the temporary, and then copy
-                    the result.  Since the "s" subobject is never
-                    constructed, this is a valid transformation.  */
-                 || CP_AGGREGATE_TYPE_P (type));
- 
        /* This would be wrong for a type with virtual bases, but they are
         caught by the assert above.  */
        return (is_empty_class (type)
--- 79,84 ----



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]