Commit a9e64c63 by Eric Botcazou Committed by Eric Botcazou

re PR middle-end/26306 (ICE on volatile array with non-constant bounds)

	PR middle-end/26306
	* gimplify.c (gimplify_expr): Only force a load for references to
	non-BLKmode volatile values.
	* doc/implement-c.texi (Qualifiers implementation): Document the
	interpretation of what a volatile access is.
	* doc/extend.texi (C++ Extensions): Rework same documentation.

From-SVN: r118900
parent c8cf9f0f
2006-11-16 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/26306
* gimplify.c (gimplify_expr): Only force a load for references to
non-BLKmode volatile values.
* doc/implement-c.texi (Qualifiers implementation): Document the
interpretation of what a volatile access is.
* doc/extend.texi (C++ Extensions): Rework same documentation.
2006-11-16 Joseph Myers <joseph@codesourcery.com>
* config/rs6000/spe.md (frob_di_df_2): Handle non-offsettable
......
......@@ -10441,11 +10441,10 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
Both the C and C++ standard have the concept of volatile objects. These
are normally accessed by pointers and used for accessing hardware. The
standards encourage compilers to refrain from optimizations
concerning accesses to volatile objects that it might perform on
non-volatile objects. The C standard leaves it implementation defined
as to what constitutes a volatile access. The C++ standard omits to
specify this, except to say that C++ should behave in a similar manner
standards encourage compilers to refrain from optimizations concerning
accesses to volatile objects. The C standard leaves it implementation
defined as to what constitutes a volatile access. The C++ standard omits
to specify this, except to say that C++ should behave in a similar manner
to C with respect to volatiles, where possible. The minimum either
standard specifies is that at a sequence point all previous accesses to
volatile objects have stabilized and no subsequent accesses have
......@@ -10455,55 +10454,28 @@ for accesses across a sequence point. The use of volatiles does not
allow you to violate the restriction on updating objects multiple times
within a sequence point.
In most expressions, it is intuitively obvious what is a read and what is
a write. For instance
@xref{Qualifiers implementation, , Volatile qualifier and the C compiler}.
@smallexample
volatile int *dst = @var{somevalue};
volatile int *src = @var{someothervalue};
*dst = *src;
@end smallexample
@noindent
will cause a read of the volatile object pointed to by @var{src} and stores the
value into the volatile object pointed to by @var{dst}. There is no
guarantee that these reads and writes are atomic, especially for objects
larger than @code{int}.
Less obvious expressions are where something which looks like an access
is used in a void context. An example would be,
The behavior differs slightly between C and C++ in the non-obvious cases:
@smallexample
volatile int *src = @var{somevalue};
*src;
@end smallexample
With C, such expressions are rvalues, and as rvalues cause a read of
the object, GCC interprets this as a read of the volatile being pointed
to. The C++ standard specifies that such expressions do not undergo
lvalue to rvalue conversion, and that the type of the dereferenced
With C, such expressions are rvalues, and GCC interprets this either as a
read of the volatile object being pointed to or only as request to evaluate
the side-effects. The C++ standard specifies that such expressions do not
undergo lvalue to rvalue conversion, and that the type of the dereferenced
object may be incomplete. The C++ standard does not specify explicitly
that it is this lvalue to rvalue conversion which is responsible for
that it is this lvalue to rvalue conversion which may be responsible for
causing an access. However, there is reason to believe that it is,
because otherwise certain simple expressions become undefined. However,
because it would surprise most programmers, G++ treats dereferencing a
pointer to volatile object of complete type in a void context as a read
of the object. When the object has incomplete type, G++ issues a
warning.
@smallexample
struct S;
struct T @{int m;@};
volatile S *ptr1 = @var{somevalue};
volatile T *ptr2 = @var{somevalue};
*ptr1;
*ptr2;
@end smallexample
In this example, a warning is issued for @code{*ptr1}, and @code{*ptr2}
causes a read of the object pointed to. If you wish to force an error on
the first case, you must force a conversion to rvalue with, for instance
a static cast, @code{static_cast<S>(*ptr1)}.
pointer to volatile object of complete type when the value is unused as
GCC would do for an equivalent type in C. When the object has incomplete
type, G++ issues a warning; if you wish to force an error, you must
force a conversion to rvalue with, for instance, a static cast.
When using a reference to volatile, G++ does not treat equivalent
expressions as accesses to volatiles, but instead issues a warning that
......
......@@ -503,7 +503,42 @@ determined by the ABI@.
@cite{What constitutes an access to an object that has volatile-qualified
type (C90 6.5.3, C99 6.7.3).}
@xref{Volatiles, , When is a Volatile Object Accessed?}.
Such an object is normally accessed by pointers and used for accessing
hardware. In most expressions, it is intuitively obvious what is a read
and what is a write. For example
@smallexample
volatile int *dst = @var{somevalue};
volatile int *src = @var{someothervalue};
*dst = *src;
@end smallexample
@noindent
will cause a read of the volatile object pointed to by @var{src} and store the
value into the volatile object pointed to by @var{dst}. There is no
guarantee that these reads and writes are atomic, especially for objects
larger than @code{int}.
However, if the volatile storage is not being modified, and the value of
the volatile storage is not used, then the situation is less obvious.
For example
@smallexample
volatile int *src = @var{somevalue};
*src;
@end smallexample
According to the C standard, such an expression is an rvalue whose type
is the unqualified version of its original type, i.e. @code{int}. Whether
GCC interprets this as a read of the volatile object being pointed to or
only as a request to evaluate the expression for its side-effects depends
on this type.
If it is a scalar type, or on most targets an aggregate type whose only
member object is of a scalar type, or a union type whose member objects
are of scalar types, the expression is interpreted by GCC as a read of
the volatile object; in the other cases, the expression is only evaluated
for its side-effects.
@end itemize
......
......@@ -5854,7 +5854,8 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
gimple_test_f, fallback);
break;
case ARRAY_REF: case ARRAY_RANGE_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
gimple_test_f, fallback);
gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
......@@ -5863,16 +5864,17 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
default:
/* Anything else with side-effects must be converted to
a valid statement before we get here. */
a valid statement before we get here. */
gcc_unreachable ();
}
*expr_p = NULL;
}
else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
&& TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
{
/* Historically, the compiler has treated a bare
reference to a volatile lvalue as forcing a load. */
/* Historically, the compiler has treated a bare reference
to a non-BLKmode volatile lvalue as forcing a load. */
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
/* Normally, we do not want to create a temporary for a
TREE_ADDRESSABLE type because such a type should not be
......@@ -5887,7 +5889,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
else
/* We can't do anything useful with a volatile reference to
incomplete type, so just throw it away. */
an incomplete type, so just throw it away. Likewise for
a BLKmode type, since any implicit inner load should
already have been turned into an explicit one by the
gimplification process. */
*expr_p = NULL;
}
......
2006-11-16 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/volatile_aggregate.adb: New test.
2006-11-16 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/29391
-- { dg-do compile }
with System;
procedure Volatile_Aggregate is
function GetArrayUpperBound return Integer is
begin
return 2;
end GetArrayUpperBound;
some_value : Integer := GetArrayUpperBound;
type Gp_Element_Type is record
Element : Integer;
end record;
type some_type is array (1 .. some_value) of Gp_Element_Type;
type Aligned_Some_Type is record
Value : aliased some_type;
end record;
for Aligned_Some_Type'Alignment use 8;
an_aligned_type : aligned_Some_Type;
my_address : system.address;
pragma Volatile (an_aligned_type);
begin
my_address := an_aligned_type.value(1)'address;
end;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment