-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When float_t and double_t types are used inside a scope with
a '#pragma clang fp eval_method, it can lead to ABI breakage. See https://godbolt.org/z/56zG4Wo91 This patch prevents this. Differential Revision: https://reviews.llvm.org/D153590
- Loading branch information
Showing
12 changed files
with
376 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// RUN: %clang_cc1 -fsyntax-only -verify %s | ||
|
||
typedef float float_t [[clang::available_only_in_default_eval_method]]; | ||
using double_t __attribute__((available_only_in_default_eval_method)) = double; | ||
|
||
// expected-error@+1{{'available_only_in_default_eval_method' attribute only applies to typedefs}} | ||
class __attribute__((available_only_in_default_eval_method)) C1 { | ||
}; | ||
// expected-error@+1{{'available_only_in_default_eval_method' attribute only applies to typedefs}} | ||
class [[clang::available_only_in_default_eval_method]] C2 { | ||
}; | ||
|
||
// expected-error@+1{{'available_only_in_default_eval_method' attribute only applies to typedefs}} | ||
struct [[clang::available_only_in_default_eval_method]] S1; | ||
// expected-error@+1{{'available_only_in_default_eval_method' attribute only applies to typedefs}} | ||
struct __attribute__((available_only_in_default_eval_method)) S2; | ||
|
||
// expected-error@+1{{'available_only_in_default_eval_method' attribute only applies to typedefs}} | ||
void __attribute__((available_only_in_default_eval_method)) foo(); | ||
// expected-error@+1{{'available_only_in_default_eval_method' attribute cannot be applied to types}} | ||
void [[clang::available_only_in_default_eval_method]] goo(); | ||
// expected-error@+1{{'available_only_in_default_eval_method' attribute cannot be applied to types}} | ||
void bar() [[clang::available_only_in_default_eval_method]]; | ||
// expected-error@+1{{'available_only_in_default_eval_method' attribute only applies to typedefs}} | ||
void barz() __attribute__((available_only_in_default_eval_method)); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// RUN: %clang_cc1 -verify -fsyntax-only -DNOERROR %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -DNOERROR %s | ||
|
||
// RUN: %clang_cc1 -verify -fsyntax-only -ffp-eval-method=source -DNOERROR %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -ffp-eval-method=source \ | ||
// RUN: -DNOERROR %s | ||
|
||
// RUN: %clang_cc1 -verify -fsyntax-only -ffp-eval-method=double %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -ffp-eval-method=double %s | ||
|
||
// RUN: %clang_cc1 -verify -fsyntax-only -ffp-eval-method=extended %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP \ | ||
// RUN: -ffp-eval-method=extended %s | ||
|
||
|
||
#ifdef NOERROR | ||
// expected-no-diagnostics | ||
typedef float float_t; | ||
typedef double double_t; | ||
#else | ||
#ifdef CPP | ||
typedef float float_t; //expected-error 9 {{cannot use type 'float_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
|
||
typedef double double_t; //expected-error 9 {{cannot use type 'double_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
#else | ||
typedef float float_t; //expected-error 7 {{cannot use type 'float_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
|
||
typedef double double_t; //expected-error 7 {{cannot use type 'double_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
#endif | ||
#endif | ||
|
||
float foo1() { | ||
#pragma clang fp eval_method(source) | ||
float a; | ||
double b; | ||
return a - b; | ||
} | ||
|
||
float foo2() { | ||
#pragma clang fp eval_method(source) | ||
float_t a; | ||
double_t b; | ||
return a - b; | ||
} | ||
|
||
void foo3() { | ||
#pragma clang fp eval_method(source) | ||
char buff[sizeof(float_t)]; | ||
char bufd[sizeof(double_t)]; | ||
buff[1] = bufd[2]; | ||
} | ||
|
||
float foo4() { | ||
#pragma clang fp eval_method(source) | ||
typedef float_t FT; | ||
typedef double_t DT; | ||
FT a; | ||
DT b; | ||
return a - b; | ||
} | ||
|
||
int foo5() { | ||
#pragma clang fp eval_method(source) | ||
int t = _Generic( 1.0L, float_t:1, default:0); | ||
int v = _Generic( 1.0L, double_t:1, default:0); | ||
return t; | ||
} | ||
|
||
void foo6() { | ||
#pragma clang fp eval_method(source) | ||
float f = (float_t)1; | ||
double d = (double_t)2; | ||
} | ||
|
||
void foo7() { | ||
#pragma clang fp eval_method(source) | ||
float c1 = (float_t)12; | ||
double c2 = (double_t)13; | ||
} | ||
|
||
float foo8() { | ||
#pragma clang fp eval_method(source) | ||
extern float_t f; | ||
extern double_t g; | ||
return f-g; | ||
} | ||
|
||
#ifdef CPP | ||
void foo9() { | ||
#pragma clang fp eval_method(source) | ||
auto resf = [](float_t f) { return f; }; | ||
auto resd = [](double_t g) { return g; }; | ||
} | ||
|
||
void foo10() { | ||
#pragma clang fp eval_method(source) | ||
using Ft = float_t; | ||
using Dt = double_t; | ||
Ft a; | ||
Dt b; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// RUN: %clang_cc1 -verify -fsyntax-only -DNOERROR %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -DNOERROR %s | ||
|
||
// RUN: %clang_cc1 -verify -fsyntax-only -ffp-eval-method=double -DNOERROR %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -ffp-eval-method=double -DNOERROR %s | ||
|
||
// RUN: %clang_cc1 -verify -fsyntax-only -ffp-eval-method=source %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -ffp-eval-method=source %s | ||
|
||
// RUN: %clang_cc1 -verify -fsyntax-only -ffp-eval-method=extended %s | ||
// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -DCPP -ffp-eval-method=extended %s | ||
|
||
#ifdef NOERROR | ||
// expected-no-diagnostics | ||
typedef float float_t; | ||
typedef double double_t; | ||
#else | ||
#ifdef CPP | ||
typedef float float_t; //expected-error 9 {{cannot use type 'float_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
|
||
typedef double double_t; //expected-error 9 {{cannot use type 'double_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
#else | ||
typedef float float_t; //expected-error 7 {{cannot use type 'float_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
|
||
typedef double double_t; //expected-error 7 {{cannot use type 'double_t' within '#pragma clang fp eval_method'; type is set according to the default eval method for the translation unit}} | ||
#endif | ||
#endif | ||
|
||
float foo1() { | ||
#pragma clang fp eval_method(double) | ||
float a; | ||
double b; | ||
return a - b; | ||
} | ||
|
||
float foo2() { | ||
#pragma clang fp eval_method(double) | ||
float_t a; | ||
double_t b; | ||
return a - b; | ||
} | ||
|
||
void foo3() { | ||
#pragma clang fp eval_method(double) | ||
char buff[sizeof(float_t)]; | ||
char bufd[sizeof(double_t)]; | ||
buff[1] = bufd[2]; | ||
} | ||
|
||
float foo4() { | ||
#pragma clang fp eval_method(double) | ||
typedef float_t FT; | ||
typedef double_t DT; | ||
FT a; | ||
DT b; | ||
return a - b; | ||
} | ||
|
||
int foo5() { | ||
#pragma clang fp eval_method(double) | ||
int t = _Generic( 1.0L, float_t:1, default:0); | ||
int v = _Generic( 1.0L, double_t:1, default:0); | ||
return t; | ||
} | ||
|
||
void foo6() { | ||
#pragma clang fp eval_method(double) | ||
float f = (float_t)1; | ||
double d = (double_t)2; | ||
} | ||
|
||
void foo7() { | ||
#pragma clang fp eval_method(double) | ||
float c1 = (float_t)12; | ||
double c2 = (double_t)13; | ||
} | ||
|
||
float foo8() { | ||
#pragma clang fp eval_method(double) | ||
extern float_t f; | ||
extern double_t g; | ||
return f-g; | ||
} | ||
|
||
#ifdef CPP | ||
void foo9() { | ||
#pragma clang fp eval_method(double) | ||
auto resf = [](float_t f) { return f; }; | ||
auto resd = [](double_t g) { return g; }; | ||
} | ||
|
||
void foo10() { | ||
#pragma clang fp eval_method(double) | ||
using Ft = float_t; | ||
using Dt = double_t; | ||
Ft a; | ||
Dt b; | ||
} | ||
#endif | ||
|
Oops, something went wrong.