2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-13 16:41:19 +08:00

re PR c/39037 (FLOAT_CONST_DECIMAL64 pragma not supported)

gcc/
	PR c/39037
	* c-common.h (mark_valid_location_for_stdc_pragma,
	valid_location_for_stdc_pragma_p, set_float_const_decimal64,
	clear_float_const_decimal64, float_const_decimal64_p): New.
	* c.opt (Wunsuffixed-float-constants): New.
	* c-lex.c (interpret_float): Use pragma FLOAT_CONST_DECIMAL64 for
	unsuffixed float constant, handle new warning.
	* c-cppbuiltin.c (c_cpp_builtins): Use cast for double constants.
	* c-decl.c (c_scope): New flag float_const_decimal64.
	(set_float_const_decimal64, clear_float_const_decimal64,
	float_const_decimal64_p): New.
	(push_scope): Set new flag.
	* c-parser.c (c_parser_translation_unit): Mark when it's valid
	to use STDC pragmas.
	(c_parser_external_declaration): Ditto.
	(c_parser_compound_statement_nostart): Ditto.
	* c-pragma.c (valid_location_for_stdc_pragma,
	mark_valid_location_for_stdc_pragma,
	valid_location_for_stdc_pragma_p, handle_stdc_pragma,
	handle_pragma_float_const_decimal64): New.
	(init_pragma): Register new pragma FLOAT_CONST_DECIMAL64.
	* cp/semantics.c (valid_location_for_stdc_pragma_p,
	set_float_const_decimal64, clear_float_const_decimal64,
	float_const_decimal64_p): New dummy functions.
	* doc/extend.texi (Decimal Float): Remove statement that the
	pragma, and suffix for double constants, are not supported.
	* doc/invoke.texi (Warning Options): List new option.
	(-Wunsuffixed-float-constants): New.

gcc/testsuite
	PR c/39037
	* gcc.dg/Wunsuffixed-float-constants-1.c: New test.
	* gcc.dg/cpp/pragma-float-const-decimal64-1.c: New test.
	* gcc.dg/dfp/float-constant-double.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-1.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-2.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-3.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-4.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-5.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-6.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-7.c: New test.
	* gcc.dg/dfp/pragma-float-const-decimal64-8.c: New test.
	* g++.dg/cpp/pragma-float-const-decimal64-1.C: New test.

From-SVN: r147259
This commit is contained in:
Janis Johnson 2009-05-07 22:34:08 +00:00 committed by Janis Johnson
parent 2995ed9a27
commit 6ec637a4b8
24 changed files with 923 additions and 15 deletions

@ -1,3 +1,34 @@
2009-05-07 Janis Johnson <janis187@us.ibm.com>
PR c/39037
* c-common.h (mark_valid_location_for_stdc_pragma,
valid_location_for_stdc_pragma_p, set_float_const_decimal64,
clear_float_const_decimal64, float_const_decimal64_p): New.
* c.opt (Wunsuffixed-float-constants): New.
* c-lex.c (interpret_float): Use pragma FLOAT_CONST_DECIMAL64 for
unsuffixed float constant, handle new warning.
* c-cppbuiltin.c (c_cpp_builtins): Use cast for double constants.
* c-decl.c (c_scope): New flag float_const_decimal64.
(set_float_const_decimal64, clear_float_const_decimal64,
float_const_decimal64_p): New.
(push_scope): Set new flag.
* c-parser.c (c_parser_translation_unit): Mark when it's valid
to use STDC pragmas.
(c_parser_external_declaration): Ditto.
(c_parser_compound_statement_nostart): Ditto.
* c-pragma.c (valid_location_for_stdc_pragma,
mark_valid_location_for_stdc_pragma,
valid_location_for_stdc_pragma_p, handle_stdc_pragma,
handle_pragma_float_const_decimal64): New.
(init_pragma): Register new pragma FLOAT_CONST_DECIMAL64.
* cp/semantics.c (valid_location_for_stdc_pragma_p,
set_float_const_decimal64, clear_float_const_decimal64,
float_const_decimal64_p): New dummy functions.
* doc/extend.texi (Decimal Float): Remove statement that the
pragma, and suffix for double constants, are not supported.
* doc/invoke.texi (Warning Options): List new option.
(-Wunsuffixed-float-constants): New.
2009-05-08 Steven Bosscher <steven@gcc.gnu.org>
* config/i386/i386.c: Do not include c-common.h.

@ -809,6 +809,11 @@ extern void warn_logical_operator (location_t, enum tree_code,
extern void check_main_parameter_types (tree decl);
extern bool c_determine_visibility (tree);
extern bool same_scalar_type_ignoring_signedness (tree, tree);
extern void mark_valid_location_for_stdc_pragma (bool);
extern bool valid_location_for_stdc_pragma_p (void);
extern void set_float_const_decimal64 (void);
extern void clear_float_const_decimal64 (void);
extern bool float_const_decimal64_p (void);
#define c_sizeof(T) c_sizeof_or_alignof_type (T, true, 1)
#define c_alignof(T) c_sizeof_or_alignof_type (T, false, 1)

@ -619,14 +619,11 @@ c_cpp_builtins (cpp_reader *pfile)
TARGET_DEC_EVAL_METHOD);
builtin_define_float_constants ("FLT", "F", "%s", float_type_node);
/* Cast the double precision constants when single precision constants are
specified. The correct result is computed by the compiler when using
macros that include a cast. This has the side-effect of making the value
unusable in const expressions. */
if (flag_single_precision_constant)
builtin_define_float_constants ("DBL", "L", "((double)%s)", double_type_node);
else
builtin_define_float_constants ("DBL", "", "%s", double_type_node);
/* Cast the double precision constants. This is needed when single
precision constants are specified or when pragma FLOAT_CONST_DECIMAL64
is used. The correct result is computed by the compiler when using
macros that include a cast. */
builtin_define_float_constants ("DBL", "L", "((double)%s)", double_type_node);
builtin_define_float_constants ("LDBL", "L", "%s", long_double_type_node);
/* For decfloat.h. */

@ -342,6 +342,9 @@ struct GTY((chain_next ("%h.outer"))) c_scope {
/* True means make a BLOCK for this scope no matter what. */
BOOL_BITFIELD keep : 1;
/* True means that an unsuffixed float constant is _Decimal64. */
BOOL_BITFIELD float_const_decimal64 : 1;
};
/* The scope currently in effect. */
@ -674,6 +677,30 @@ keep_next_level (void)
keep_next_level_flag = true;
}
/* Set the flag for the FLOAT_CONST_DECIMAL64 pragma being ON. */
void
set_float_const_decimal64 (void)
{
current_scope->float_const_decimal64 = true;
}
/* Clear the flag for the FLOAT_CONST_DECIMAL64 pragma. */
void
clear_float_const_decimal64 (void)
{
current_scope->float_const_decimal64 = false;
}
/* Return nonzero if an unsuffixed float constant is _Decimal64. */
bool
float_const_decimal64_p (void)
{
return current_scope->float_const_decimal64;
}
/* Identify this scope as currently being filled with parameters. */
void
@ -705,6 +732,13 @@ push_scope (void)
keep_next_level_flag = false;
next_is_function_body = false;
/* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */
if (current_scope->outer)
current_scope->float_const_decimal64
= current_scope->outer->float_const_decimal64;
else
current_scope->float_const_decimal64 = false;
}
else
{
@ -717,6 +751,12 @@ push_scope (void)
else
scope = GGC_CNEW (struct c_scope);
/* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */
if (current_scope)
scope->float_const_decimal64 = current_scope->float_const_decimal64;
else
scope->float_const_decimal64 = false;
scope->keep = keep_next_level_flag;
scope->outer = current_scope;
scope->depth = current_scope ? (current_scope->depth + 1) : 0;

@ -617,11 +617,21 @@ interpret_float (const cpp_token *token, unsigned int flags)
char *copy;
size_t copylen;
/* Default (no suffix) is double. */
/* Default (no suffix) depends on whether the FLOAT_CONST_DECIMAL64
pragma has been used and is either double or _Decimal64. Types
that are not allowed with decimal float default to double. */
if (flags & CPP_N_DEFAULT)
{
flags ^= CPP_N_DEFAULT;
flags |= CPP_N_MEDIUM;
if (((flags & CPP_N_HEX) == 0) && ((flags & CPP_N_IMAGINARY) == 0))
{
warning (OPT_Wunsuffixed_float_constants,
"unsuffixed float constant");
if (float_const_decimal64_p ())
flags |= CPP_N_DFLOAT;
}
}
/* Decode _Fract and _Accum. */

@ -976,6 +976,7 @@ c_parser_translation_unit (c_parser *parser)
else
{
void *obstack_position = obstack_alloc (&parser_obstack, 0);
mark_valid_location_for_stdc_pragma (false);
do
{
ggc_collect ();
@ -1060,7 +1061,9 @@ c_parser_external_declaration (c_parser *parser)
c_parser_consume_token (parser);
break;
case CPP_PRAGMA:
mark_valid_location_for_stdc_pragma (true);
c_parser_pragma (parser, pragma_external);
mark_valid_location_for_stdc_pragma (false);
break;
case CPP_PLUS:
case CPP_MINUS:
@ -3350,17 +3353,20 @@ c_parser_compound_statement_nostart (c_parser *parser)
{
bool last_stmt = false;
bool last_label = false;
bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
c_parser_consume_token (parser);
return;
}
mark_valid_location_for_stdc_pragma (true);
if (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
location_t err_loc = c_parser_peek_token (parser)->location;
/* Read zero or more forward-declarations for labels that nested
functions can jump to. */
mark_valid_location_for_stdc_pragma (false);
while (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
c_parser_consume_token (parser);
@ -3391,6 +3397,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
/* We must now have at least one statement, label or declaration. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
c_parser_consume_token (parser);
return;
@ -3409,12 +3416,14 @@ c_parser_compound_statement_nostart (c_parser *parser)
label_loc = c_parser_peek_token (parser)->location;
last_label = true;
last_stmt = false;
mark_valid_location_for_stdc_pragma (false);
c_parser_label (parser);
}
else if (!last_label
&& c_parser_next_token_starts_declspecs (parser))
{
last_label = false;
mark_valid_location_for_stdc_pragma (false);
c_parser_declaration_or_fndef (parser, true, true, true, true);
if (last_stmt)
pedwarn_c90 (loc,
@ -3441,6 +3450,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
ext = disable_extension_diagnostics ();
c_parser_consume_token (parser);
last_label = false;
mark_valid_location_for_stdc_pragma (false);
c_parser_declaration_or_fndef (parser, true, true, true, true);
/* Following the old parser, __extension__ does not
disable this diagnostic. */
@ -3467,6 +3477,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
}
else if (c_parser_next_token_is (parser, CPP_EOF))
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
return;
}
@ -3474,6 +3485,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
{
if (parser->in_if_block)
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
error_at (loc, """expected %<}%> before %<else%>");
return;
}
@ -3489,6 +3501,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
statement:
last_label = false;
last_stmt = true;
mark_valid_location_for_stdc_pragma (false);
c_parser_statement_after_labels (parser);
}
@ -3497,6 +3510,8 @@ c_parser_compound_statement_nostart (c_parser *parser)
if (last_label)
error_at (label_loc, "label at end of compound statement");
c_parser_consume_token (parser);
/* Restore the value we started with. */
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
}
/* Parse a label (C90 6.6.1, C99 6.8.1).

@ -1162,6 +1162,116 @@ handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
inform (input_location, "#pragma message: %s", TREE_STRING_POINTER (message));
}
/* Mark whether the current location is valid for a STDC pragma. */
static bool valid_location_for_stdc_pragma;
void
mark_valid_location_for_stdc_pragma (bool flag)
{
valid_location_for_stdc_pragma = flag;
}
/* Return true if the current location is valid for a STDC pragma. */
bool
valid_location_for_stdc_pragma_p (void)
{
return valid_location_for_stdc_pragma;
}
enum pragma_switch_t { ON, OFF, DEFAULT, BAD };
/* A STDC pragma must appear outside of external declarations or
preceding all explicit declarations and statements inside a compound
statement; its behavior is undefined if used in any other context.
It takes a switch of ON, OFF, or DEFAULT. */
static enum pragma_switch_t
handle_stdc_pragma (const char *pname)
{
const char *arg;
tree t;
enum pragma_switch_t ret;
if (!valid_location_for_stdc_pragma_p ())
{
warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
pname);
return BAD;
}
if (pragma_lex (&t) != CPP_NAME)
{
warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
return BAD;
}
arg = IDENTIFIER_POINTER (t);
if (!strcmp (arg, "ON"))
ret = ON;
else if (!strcmp (arg, "OFF"))
ret = OFF;
else if (!strcmp (arg, "DEFAULT"))
ret = DEFAULT;
else
{
warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
return BAD;
}
if (pragma_lex (&t) != CPP_EOF)
{
warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
return BAD;
}
return ret;
}
/* #pragma STDC FLOAT_CONST_DECIMAL64 ON
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
static void
handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy))
{
if (c_dialect_cxx ())
{
if (warn_unknown_pragmas > in_system_header)
warning (OPT_Wunknown_pragmas,
"%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
" for C++");
return;
}
if (!targetm.decimal_float_supported_p ())
{
if (warn_unknown_pragmas > in_system_header)
warning (OPT_Wunknown_pragmas,
"%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
" on this target");
return;
}
pedwarn (input_location, OPT_pedantic,
"ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
{
case ON:
set_float_const_decimal64 ();
break;
case OFF:
case DEFAULT:
clear_float_const_decimal64 ();
break;
case BAD:
break;
}
}
/* A vector of registered pragma callbacks. */
DEF_VEC_O (pragma_handler);
@ -1330,6 +1440,9 @@ init_pragma (void)
c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
handle_pragma_float_const_decimal64);
c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);

@ -476,6 +476,10 @@ Wunknown-pragmas
C ObjC C++ ObjC++ Warning
Warn about unrecognized pragmas
Wunsuffixed-float-constants
C ObjC Var(warn_unsuffixed_float_constants) Warning
Warn about unsuffixed float constants
Wunused-macros
C ObjC C++ ObjC++ Warning
Warn about macros defined in the main file that are not used

@ -5050,4 +5050,23 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
? boolean_true_node : boolean_false_node);
}
/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
which is ignored for C++. */
void
set_float_const_decimal64 (void)
{
}
void
clear_float_const_decimal64 (void)
{
}
bool
float_const_decimal64_p (void)
{
return 0;
}
#include "gt-cp-semantics.h"

@ -957,10 +957,6 @@ GCC support of decimal float as specified by the draft technical report
is incomplete:
@itemize @bullet
@item
Pragma @code{FLOAT_CONST_DECIMAL64} is not supported, nor is the @samp{d}
suffix for literal constants of type @code{double}.
@item
When the value of a decimal floating type cannot be represented in the
integer type to which it is being converted, the result is undefined

@ -259,8 +259,8 @@ Objective-C and Objective-C++ Dialects}.
-Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol
-Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized @gol
-Wunknown-pragmas -Wno-pragmas -Wunreachable-code @gol
-Wunused -Wunused-function -Wunused-label -Wunused-parameter @gol
-Wunused-value -Wunused-variable @gol
-Wunsuffixed-float-constants -Wunused -Wunused-function @gol
-Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable @gol
-Wvariadic-macros -Wvla @gol
-Wvolatile-register-var -Wwrite-strings}
@ -4218,6 +4218,15 @@ minimum maximum, so we do not diagnose overlength strings in C++@.
This option is implied by @option{-pedantic}, and can be disabled with
@option{-Wno-overlength-strings}.
@item -Wunsuffixed-float-constants
@opindex Wunsuffixed-float-constants
GCC will issue a warning for any floating constant that does not have
a suffix. When used together with @option{-Wsystem-headers} it will
warn about such constants in system header files. This can be useful
when preparing code to use with the @code{FLOAT_CONST_DECIMAL64} pragma
from the decimal floating-point extension to C99.
@end table
@node Debugging Options

@ -1,3 +1,19 @@
2009-05-07 Janis Johnson <janis187@us.ibm.com>
PR c/39037
* gcc.dg/Wunsuffixed-float-constants-1.c: New test.
* gcc.dg/cpp/pragma-float-const-decimal64-1.c: New test.
* gcc.dg/dfp/float-constant-double.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-1.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-2.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-3.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-4.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-5.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-6.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-7.c: New test.
* gcc.dg/dfp/pragma-float-const-decimal64-8.c: New test.
* g++.dg/cpp/pragma-float-const-decimal64-1.C: New test.
2009-05-07 Jakub Jelinek <jakub@redhat.com>
PR middle-end/40057

@ -0,0 +1,5 @@
// { dg-do compile }
// { dg-options "-Wunknown-pragmas" }
#pragma STDC FLOAT_CONST_DECIMAL64 ON // { dg-warning "not supported for C\\\+\\\+" }
double d = 1.0;

@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wunsuffixed-float-constants" } */
#define VAL 0.5;
double a = 1.1d;
/* With FLOAT_CONST_DECIMAL64 switched to ON these would have type
_Decimal64. */
double b = VAL; /* { dg-warning "unsuffixed float constant" } */
double c = 1.2; /* { dg-warning "unsuffixed float constant" } */
/* With FLOAT_CONST_DECIMAL64 switched to ON these are still binary. */
double d = 0x5.0p1; /* No warning for hex constant. */
double e = 3.1i; /* No warning for imaginary constant. */

@ -0,0 +1,5 @@
/* { dg-do compile { target { ! dfp } } } */
/* { dg-options "-std=gnu99 -Wunknown-pragmas" } */
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "not supported on this target" } */
double d = 1.0;

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99" } */
/* Constant float values of type double in <float.h> are suffixed with L
and cast to double so they can be used within code that uses pragma
FLOAT_CONST_DECIMAL64. If they were not suffixed then use of the macro
would have them interpreted as _Decimal64, leading to errors when used
in expressions with other operands of type double. */
#include <float.h>
extern double a, b, c, d;
void
foo ()
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON")
a = 0.1d * DBL_MAX;
b = DBL_EPSILON * 10.0d;
c = DBL_MIN * 200.0d;
}

@ -0,0 +1,85 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Verify that the pragma has the expected result by using unsuffixed
float constants as operands in expressions that would mix binary and
decimal operands if the pragma had no effect, or the wrong effect. */
#pragma STDC FLOAT_CONST_DECIMAL64 ON
double a = 1.0 * 2.0dd;
double
f1 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
double b = 2.0 * 3.0d;
{
double c = 3.0 * 4.0d;
b = b + c;
}
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON
double d = 4.0 * 5.0dd;
b = b + d;
}
{
/* Default is OFF. */
#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT
double e = 5.0 * 6.0d;
b = b + e;
}
return b;
}
double
f2 (void)
{
/* Use value from outer scope, which is ON. */
double b = 2.0 * 3.0dd;
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
double c = 3.0 * 4.0d;
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON
double d = 4.0 * 5.0dd;
{
#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT
double e = 5.0 * 6.0d;
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON
double f = 6.0 * 7.0dd;
b = a + b + c + d + e + f;
}
}
}
}
return b;
}
/* Use previous value from this scope, which is ON. */
double f = 6.0 * 7.0dd;
double
f3 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
double b = 2.0 * 3.0d;
return b + f;
}
/* Return to the state from this scope, which is ON. */
double g = 7.0 + 8.0dd;

@ -0,0 +1,86 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Verify that the pragma has the expected result by using unsuffixed
float constants as operands in expressions that would mix binary and
decimal operands if the pragma had no effect, or the wrong effect.
Use _Pragma rather than #pragma. */
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON")
double a = 1.0 * 2.0dd;
double
f1 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF")
double b = 2.0 * 3.0d;
{
double c = 3.0 * 4.0d;
b = b + c;
}
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON")
double d = 4.0 * 5.0dd;
b = b + d;
}
{
/* Default is OFF. */
_Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT")
double e = 5.0 * 6.0d;
b = b + e;
}
return b;
}
double
f2 (void)
{
/* Use value from outer scope, which is ON. */
double b = 2.0 * 3.0dd;
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF")
double c = 3.0 * 4.0d;
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON")
double d = 4.0 * 5.0dd;
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT")
double e = 5.0 * 6.0d;
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON")
double f = 6.0 * 7.0dd;
b = a + b + c + d + e + f;
}
}
}
}
return b;
}
/* Use previous value from this scope, which is ON. */
double f = 6.0 * 7.0dd;
double
f3 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF")
double b = 2.0 * 3.0d;
return b + f;
}
/* Return to the state from this scope, which is ON. */
double g = 7.0 + 8.0dd;

@ -0,0 +1,83 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New). */
/* Check that defining macros whose names are the same as the tokens used
in the pragma doesn't affect use of the pragma. */
#define ON YES
#define OFF NO
#define DEFAULT NOPE
#define STDC OFFICIAL
#define FLOAT_CONST_DECIMAL64 NEW_PRAGMA
double a;
void
f1a (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON
a = 1.0dd + 2.0;
}
void
f1b (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
a = 2.0d + 3.0;
}
void
f1c (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT
a = 3.0d + 4.0;
}
/* Check that a macro can be used for the entire pragma. */
#define PRAGMA(x) _Pragma (#x)
#define DEFAULT_FLOAT_IS_DECIMAL PRAGMA(STDC FLOAT_CONST_DECIMAL64 ON)
#define DEFAULT_FLOAT_IS_BINARY PRAGMA(STDC FLOAT_CONST_DECIMAL64 OFF)
void
f2a (void)
{
DEFAULT_FLOAT_IS_DECIMAL
a = 5.0 * 6.0dd;
}
void
f2b (void)
{
DEFAULT_FLOAT_IS_BINARY
a = 6.0 * 7.0d;
}
/* _Pragma can be used with macros, including the use of a macro for the
switch. */
#undef ON
#undef OFF
#undef DEFAULT
#undef STDC
#undef FLOAT_CONST_DECIMAL64
#define SWITCH ON
#define FLOAT_CONST_DECIMAL64(x) PRAGMA(STDC FLOAT_CONST_DECIMAL64 x)
void
f3a (void)
{
FLOAT_CONST_DECIMAL64(SWITCH)
a = 1.0 * 7.0dd;
}
void
f3b (void)
{
FLOAT_CONST_DECIMAL64(OFF)
a = 1.0 + 2.0d;
}

@ -0,0 +1,46 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Check that malformed versions of pragma STDC FLOAT_CONST_DECIMAL64
are detected. */
double a;
void f1 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 /* { dg-warning "malformed" } */
a = 1.0;
}
void f2 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 DFP /* { dg-warning "malformed" } */
a = 2.0;
}
void f3 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON DFP /* { dg-warning "junk at end" } */
a = 3.0;
}
void f4 (void)
{
_Pragma ( "STDC FLOAT_CONST_DECIMAL64" ) /* { dg-warning "malformed" } */
a = 1.0;
}
void f5 (void)
{
_Pragma ( "STDC FLOAT_CONST_DECIMAL64 DFP" ) /* { dg-warning "malformed" } */
a = 2.0;
}
void f6 (void)
{
_Pragma ( "STDC FLOAT_CONST_DECIMAL64 ON DFP" ) /* { dg-warning "junk at end" } */
a = 3.0;
}

@ -0,0 +1,46 @@
/* { dg-do compile } */
/* { dg-options "-std=c99 -pedantic" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Check that there is a pedantic warning for the use of pragma
STD FLOAT_CONST_DECIMAL64. */
double a;
void f1 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "ISO C" } */
a = 1.0;
}
void f2 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-warning "ISO C" } */
a = 2.0;
}
void f3 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT /* { dg-warning "ISO C" } */
a = 3.0;
}
void f4 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") /* { dg-warning "ISO C" } */
a = 1.0;
}
void f5 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") /* { dg-warning "ISO C" } */
a = 2.0;
}
void f6 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT") /* { dg-warning "ISO C" } */
a = 3.0;
}

@ -0,0 +1,46 @@
/* { dg-do compile } */
/* { dg-options "-std=c99 -pedantic-errors" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Check that there is a pedantic error for the use of pragma
STD FLOAT_CONST_DECIMAL64. */
double a;
void f1 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "ISO C" } */
a = 1.0;
}
void f2 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-error "ISO C" } */
a = 2.0;
}
void f3 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT /* { dg-error "ISO C" } */
a = 3.0;
}
void f4 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") /* { dg-error "ISO C" } */
a = 1.0;
}
void f5 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") /* { dg-error "ISO C" } */
a = 2.0;
}
void f6 (void)
{
_Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT") /* { dg-error "ISO C" } */
a = 3.0;
}

@ -0,0 +1,39 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Check that when pragma FLOAT_CONST_DECIMAL64 is in effect so that
unsuffixed constants are _Decimal64, invalid types are still reported
as invalid. */
double
f1 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
double a = 0x1.0p1;
double b = 1.0i;
return a + b;
}
double
f2 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
double a = 0x1.0p1dd; /* { dg-error "with hex" } */
double b = 1.0idd; /* { dg-error "invalid suffix" } */
return a + b;
}
double
f3 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON
double a = 0x1.0p1; /* Hex constant is not affected by pragma. */
double b = 1.0i; /* Imaginary constant is not affected by pragma. */
return a + b;
}

@ -0,0 +1,174 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
Pragma STDC FLOAT_CONST_DECIMAL64 "shall occur either outside external
declarations or preceding all explicit declarations and statements
inside a compound statement." */
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
#define MAX 200
#pragma STDC FLOAT_CONST_DECIMAL64 ON
double a;
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
struct S1 {
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
int i;
int j;
};
struct S2 {
int i;
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
int j;
};
struct S3 {
int i;
int j;
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
};
enum E1 {
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */
one,
two
};
enum E2 {
red,
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */
blue
};
enum E3 {
cat,
dog
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */
};
double
#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-error "#pragma" } */
b;
double
f1 (void)
{
#pragma STDC FLOAT_CONST_DECIMAL64 ON
return a;
}
double
f2 (void)
{
double b;
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
b = 0.5;
return a + b;
}
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
double
f3 (void)
{
typedef double b32;
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
b32 b = 0.5;
return b;
}
double
f4 (int i)
{
top:
#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-warning "invalid location" } */
if (i == 0)
return a;
a *= 2.;
i = 0;
goto top;
}
double
f5 (int i)
{
a = a * i;
#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-warning "invalid location" } */
return a * 2.;
}
double
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */
f6 (void)
{
return a;
}
double
f7
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */
(void) /* { dg-error "before" } */
{
return a;
}
double
f8 (void)
{
{
#pragma STDC FLOAT_CONST_DECIMAL64 OFF
}
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
return a;
}
extern void foo9 (void *);
double
f9 (void)
{
__label__ here;
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
foo9 (&&here);
here:
return a;
}
double
f10 (void)
{
void foo10 (void)
{
a = 1.0;
}
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
return a;
}
double
f11 (void)
{
__extension__
struct A {
struct { char a; };
char b;
};
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
return a;
}
double
f12 (void)
{
__extension__ ({ a = 0.5; });
#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */
return a;
}