The C++ frontend drops qualifiers when performing pointer dereference: void foo(int * __restrict p, int * __restrict__ q, int i) { *q = p[i]; }
;; Function void foo(int*, int*, int) (null) ;; enabled by -tree-original <<cleanup_point <<< Unknown tree: expr_stmt (void) (*(int *) q = *((int *) p + (long unsigned int) ((long unsigned int) i * 4))) >>> >>; while this isn't a big issue for the plain *q (the cast is stripped as useless during gimplification), the second cast results in the gimplifier generating an unqualified temporary to do the dereference: void foo(int*, int*, int) (int * restrict p, int * restrict q, int i) { long unsigned int D.2088; long unsigned int D.2089; int * D.2090; int D.2091; D.2088 = (long unsigned int) i; D.2089 = D.2088 * 4; D.2090 = p + D.2089; D.2091 = *D.2090; *q = D.2091; } The C frontend seems to get away without doing this conversion, the C++ frontend does it here: typeck.c:decay_conversion /* [basic.lval] Non-class rvalues always have cv-unqualified types. */ type = TREE_TYPE (exp); if (!CLASS_TYPE_P (type) && cp_type_quals (type)) exp = build_nop (TYPE_MAIN_VARIANT (type), exp); called from #1 0x0000000000657c35 in cp_build_indirect_ref (ptr=0x7ffff7edcf30, errorstring=0x120f491 "unary *", complain=3) at /space/rguenther/src/svn/trunk/gcc/cp/typeck.c:2493 2490 if (ptr == current_class_ptr) 2491 return current_class_ref; 2492 2493 pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE 2494 ? ptr : decay_conversion (ptr)); 2495 type = TREE_TYPE (pointer); The C++ frontend in this way currently pessimizes code by emitting dereferences of non-restrict qualified pointers where the user used a restrict qualified pointer. Where can this be fixed? I currently have a hack to not strip restrict qualifiers in decay_conversion, but that feels a little too hackish. What's the important piece of decay_conversion that is necessary for indirect refs? Thanks, Richard.