X-Git-Url: https://gcc.gnu.org/git/?a=blobdiff_plain;f=gcc%2Fcp%2Ftypeck.c;h=de3c0596e3c0fcab6dea4be6f8e70c9b29032c9c;hb=046fff34a53cc09dd10ccec249426e411fb64693;hp=8a71746c00e91488b0eb85927dd5794da57b4061;hpb=a6f5b2d3eb0ee8fb587e1841f511228ff6c25cc4;p=gcc.git diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 8a71746c00e9..de3c0596e3c0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -203,28 +203,33 @@ qualify_type_recursive (t1, t2) if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2)) || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))) { - tree tt1 = TREE_TYPE (t1); - tree tt2 = TREE_TYPE (t2); + tree tt1; + tree tt2; tree b1; int type_quals; tree tgt; tree attributes = (*targetm.merge_type_attributes) (t1, t2); - if (TREE_CODE (tt1) == OFFSET_TYPE) + if (TYPE_PTRMEM_P (t1)) { - b1 = TYPE_OFFSET_BASETYPE (tt1); - tt1 = TREE_TYPE (tt1); - tt2 = TREE_TYPE (tt2); + b1 = TYPE_PTRMEM_CLASS_TYPE (t1); + tt1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1); + tt2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2); } else - b1 = NULL_TREE; + { + b1 = NULL_TREE; + tt1 = TREE_TYPE (t1); + tt2 = TREE_TYPE (t2); + } type_quals = (cp_type_quals (tt1) | cp_type_quals (tt2)); tgt = qualify_type_recursive (tt1, tt2); tgt = cp_build_qualified_type (tgt, type_quals); if (b1) - tgt = build_offset_type (b1, tgt); - t1 = build_pointer_type (tgt); + t1 = build_ptrmem_type (b1, tgt); + else + t1 = build_pointer_type (tgt); t1 = build_type_attribute_variant (t1, attributes); } return t1; @@ -857,7 +862,7 @@ comp_array_types (cmp, t1, t2, strict) return 1; /* If one of the arrays is dimensionless, and the other has a - dimension, they are of different types. However, it is legal to + dimension, they are of different types. However, it is valid to write: extern int a[]; @@ -897,7 +902,7 @@ comptypes (t1, t2, strict) extern int (*i)[]; int (*i)[8]; - is not legal, for example. */ + is invalid, for example. */ strict &= ~COMPARE_REDECLARATION; /* Suppress errors caused by previously reported errors */ @@ -1543,7 +1548,7 @@ expr_sizeof (e) cxx_incomplete_type_error (e, TREE_TYPE (e)); return c_sizeof (char_type_node); } - /* It's illegal to say `sizeof (X::i)' for `i' a non-static data + /* It's invalid to say `sizeof (X::i)' for `i' a non-static data member unless you're in a non-static member of X. So hand off to resolve_offset_ref. [expr.prim] */ else if (TREE_CODE (e) == OFFSET_REF) @@ -3618,7 +3623,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) return error_mark_node; } - /* Issue warnings about peculiar, but legal, uses of NULL. */ + /* Issue warnings about peculiar, but valid, uses of NULL. */ if (/* It's reasonable to use pointer values as operands of && and ||, so NULL is no exception. */ !(code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) @@ -4251,6 +4256,24 @@ build_unary_op (code, xarg, noconvert) TREE_OPERAND (arg, 1)); return error_mark_node; } + else if (TREE_CODE (arg) == COMPONENT_REF + && TREE_CODE (TREE_OPERAND (arg, 0)) == INDIRECT_REF + && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)) + == INTEGER_CST)) + { + /* offsetof idiom, fold it. */ + tree field = TREE_OPERAND (arg, 1); + tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); + tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)), + decl_type_context (field), + ba_check, NULL); + + rval = build_base_path (PLUS_EXPR, rval, binfo, 1); + rval = build1 (NOP_EXPR, argtype, rval); + TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0)); + addr = fold (build (PLUS_EXPR, argtype, rval, + cp_convert (argtype, byte_position (field)))); + } else addr = build1 (ADDR_EXPR, argtype, arg); @@ -4390,9 +4413,7 @@ unary_complex_lvalue (code, arg) return error_mark_node; } - type = build_offset_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t)); - type = build_pointer_type (type); - + type = build_ptrmem_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t)); t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1)); return t; } @@ -5713,7 +5734,7 @@ dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum) if (TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); - /* Issue warnings about peculiar, but legal, uses of NULL. */ + /* Issue warnings about peculiar, but valid, uses of NULL. */ if (ARITHMETIC_TYPE_P (type) && expr == null_node) { if (fndecl) @@ -6065,7 +6086,7 @@ maybe_warn_about_returning_address_of_local (retval) } } -/* Check that returning RETVAL from the current function is legal. +/* Check that returning RETVAL from the current function is valid. Return an expression explicitly showing all conversions required to change RETVAL into the function return type, and to assign it to the DECL_RESULT for the function. */