OFFSET_TYPE is treated as an integral type for the purpose of conversion in fold-const.c. However, the GIMPLE verifier disagrees, leading to verification errors when a cast from boolean to offset type is gimplified.
Bootstrapped/regtested x86_64-pc-linux-gnu, ok for mainline? Paolo 2012-05-16 Paolo Bonzini <bonz...@gnu.org> * tree-cfg.c (verify_gimple_assign_unary): Allow conversion from non-integer integral types to offset type and vice versa. 2012-05-16 Paolo Bonzini <bonz...@gnu.org> * g++.dg/torture/pr53336.C: New testcase. Index: tree-cfg.c =================================================================== --- tree-cfg.c (revisione 186903) +++ tree-cfg.c (copia locale) @@ -3374,11 +3374,11 @@ verify_gimple_assign_unary (gimple stmt) || ptrofftype_p (sizetype)))) return false; - /* Allow conversion from integer to offset type and vice versa. */ + /* Allow conversion from integral to offset type and vice versa. */ if ((TREE_CODE (lhs_type) == OFFSET_TYPE - && TREE_CODE (rhs1_type) == INTEGER_TYPE) + && INTEGRAL_TYPE_P (rhs1_type)) || (TREE_CODE (lhs_type) == INTEGER_TYPE - && TREE_CODE (rhs1_type) == OFFSET_TYPE)) + && INTEGRAL_TYPE_P (rhs1_type))) return false; /* Otherwise assert we are converting between types of the Index: testsuite/g++.dg/torture/pr53336.C =================================================================== --- testsuite/g++.dg/torture/pr53336.C (revisione 0) +++ testsuite/g++.dg/torture/pr53336.C (revisione 0) @@ -0,0 +1,45 @@ +// { dg-do compile } + +bool foo(); + +struct C +{ + C() + { + if (foo()) + foo(); + } +}; + +struct S +{ + struct dummy + { + int i_; + }; + typedef int dummy::*bool_type; + + operator bool_type() const + { + return foo() ? &dummy::i_ : 0; + } +}; + +int x; + +struct adaptor +{ + C c; + + virtual void bar() + { + if (S()) + x = 0; + } +}; + +int main() +{ + adaptor a; +} +