4 changes: 2 additions & 2 deletions clang/test/Analysis/stack-addr-ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ int* f3(int x, int *y) {

void* compound_literal(int x, int y) {
if (x)
return &(unsigned short){((unsigned short)0x22EF)}; // expected-warning{{Address of stack memory}}
return &(unsigned short){((unsigned short)0x22EF)}; // expected-warning{{Address of stack memory}} expected-warning{{address of stack memory}}

int* array[] = {};
struct s { int z; double y; int w; };

if (y)
return &((struct s){ 2, 0.4, 5 * 8 }); // expected-warning{{Address of stack memory}}
return &((struct s){ 2, 0.4, 5 * 8 }); // expected-warning{{Address of stack memory}} expected-warning{{address of stack memory}}


void* p = &((struct s){ 42, 0.4, x ? 42 : 0 });
Expand Down
2 changes: 1 addition & 1 deletion clang/test/C/drs/dr0xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ _Static_assert(__builtin_types_compatible_p(struct S { int a; }, union U { int a
*/
void dr031(int i) {
switch (i) {
case __INT_MAX__ + 1: break; /* expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} */
case __INT_MAX__ + 1: break; /* expected-warning {{overflow in expression; result is -2'147'483'648 with type 'int'}} */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch"
/* Silence the targets which issue:
Expand Down
2 changes: 1 addition & 1 deletion clang/test/C/drs/dr2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ void dr258(void) {
void dr261(void) {
/* This is still an integer constant expression despite the overflow. */
enum e1 {
ex1 = __INT_MAX__ + 1 /* expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} */
ex1 = __INT_MAX__ + 1 /* expected-warning {{overflow in expression; result is -2'147'483'648 with type 'int'}} */
};

/* This is not an integer constant expression, because of the comma operator,
Expand Down
35 changes: 16 additions & 19 deletions clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV

// Make sure SV_DispatchThreadID translated into dx.thread.id.

const RWBuffer<float> In;
RWBuffer<float> Out;

// CHECK: define void @foo()
// CHECK: %[[ID:[0-9a-zA-Z]+]] = call i32 @llvm.dx.thread.id(i32 0)
// CHECK: call void @"?foo@@YAXH@Z"(i32 %[[ID]])
// CHECK: define void @foo()
// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.dx.thread.id(i32 0)
// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.spv.thread.id(i32 0)
// CHECK: call void @{{.*}}foo{{.*}}(i32 %[[#ID]])
[shader("compute")]
[numthreads(8,8,1)]
void foo(uint Idx : SV_DispatchThreadID) {
Out[Idx] = In[Idx];
}
void foo(uint Idx : SV_DispatchThreadID) {}

// CHECK: define void @bar()
// CHECK: %[[ID_X:[0-9a-zA-Z]+]] = call i32 @llvm.dx.thread.id(i32 0)
// CHECK: %[[ID_X_:[0-9a-zA-Z]+]] = insertelement <2 x i32> poison, i32 %[[ID_X]], i64 0
// CHECK: %[[ID_Y:[0-9a-zA-Z]+]] = call i32 @llvm.dx.thread.id(i32 1)
// CHECK: %[[ID_XY:[0-9a-zA-Z]+]] = insertelement <2 x i32> %[[ID_X_]], i32 %[[ID_Y]], i64 1
// CHECK: call void @"?bar@@YAXT?$__vector@H$01@__clang@@@Z"(<2 x i32> %[[ID_XY]])
// CHECK: define void @bar()
// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.dx.thread.id(i32 0)
// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.spv.thread.id(i32 0)
// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.dx.thread.id(i32 1)
// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.spv.thread.id(i32 1)
// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
// CHECK-DXIL: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]])
[shader("compute")]
[numthreads(8,8,1)]
void bar(uint2 Idx : SV_DispatchThreadID) {
Out[Idx.y] = In[Idx.x];
}
void bar(uint2 Idx : SV_DispatchThreadID) {}

102 changes: 102 additions & 0 deletions clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | FileCheck %s

// CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 20
// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 24
// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = constant i64 32
// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = constant i64 40
// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden constant i64 48
// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = constant i64 56
// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden constant i64 64
// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12

@interface NSObject {
Expand All @@ -14,12 +21,105 @@ @interface StaticLayout : NSObject
@implementation StaticLayout {
int static_layout_ivar;
}

// CHECK-LABEL: define internal void @"\01-[StaticLayout meth]"
-(void)meth {
static_layout_ivar = 0;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_StaticLayout
// CHECK: getelementptr inbounds i8, ptr %0, i64 20
}
@end

@interface SuperClass : NSObject
@property (nonatomic, assign) int superClassProperty;
@end

@implementation SuperClass {
int superClassIvar; // Declare an ivar
}

// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
- (void)superClassMethod {
_superClassProperty = 42;
superClassIvar = 10;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
// CHECK: getelementptr inbounds i8, ptr %1, i64 20
}

// Implicitly synthesized method here
// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
// CHECK: getelementptr inbounds i8, ptr %0, i64 24

// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
// CHECK: getelementptr inbounds i8, ptr %1, i64 24
@end

@interface IntermediateClass : SuperClass {
double intermediateClassIvar;

@protected
int intermediateClassIvar2;
}
@property (nonatomic, strong) SuperClass *intermediateProperty;
@end

@implementation IntermediateClass
@synthesize intermediateProperty = _intermediateProperty;

// CHECK-LABEL: define internal void @"\01-[IntermediateClass intermediateClassMethod]"
- (void)intermediateClassMethod {
intermediateClassIvar = 3.14;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
// CHECK: getelementptr inbounds i8, ptr %0, i64 32
}

// CHECK-LABEL: define internal void @"\01-[IntermediateClass intermediateClassPropertyMethod]"
- (void)intermediateClassPropertyMethod {
self.intermediateProperty = 0;
// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
// CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr noundef null)
}

// CHECK-LABEL: define internal void @"\01-[IntermediateClass intermediateClassPropertyMethodDirect]"
- (void)intermediateClassPropertyMethodDirect {
_intermediateProperty = 0;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
// CHECK: getelementptr inbounds i8, ptr %0, i64 48
}
@end

@interface SubClass : IntermediateClass {
double subClassIvar;
}
@property (nonatomic, assign) SubClass *subClassProperty;
@end

@implementation SubClass

// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
- (void)subclassVar {
subClassIvar = 6.28;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SubClass
// CHECK: getelementptr inbounds i8, ptr %0, i64 56
}

// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
-(void)intermediateSubclassVar {
intermediateClassIvar = 3.14;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
// CHECK: getelementptr inbounds i8, ptr %0, i64 32
}

// Implicit synthesized method here:
// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
// CHECK: getelementptr inbounds i8, ptr %0, i64 64

// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
// CHECK: getelementptr inbounds i8, ptr %1, i64 64
@end

@interface NotNSObject {
int these, might, change;
}
Expand All @@ -31,6 +131,8 @@ @interface NotStaticLayout : NotNSObject
@implementation NotStaticLayout {
int not_static_layout_ivar;
}

// CHECK-LABEL: define internal void @"\01-[NotStaticLayout meth]"
-(void)meth {
not_static_layout_ivar = 0;
// CHECK: load i64, ptr @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Driver/freebsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,7 @@
// RELOCATABLE-NOT: "-l
// RELOCATABLE-NOT: crt{{[^./\\]+}}.o

// Check that the -X and --no-relax flags are passed to the linker on riscv64
// RUN: %clang --target=riscv64-unknown-freebsd -mno-relax -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=RISCV64-FLAGS %s
// RISCV64-FLAGS: "-X" "--no-relax"
5 changes: 5 additions & 0 deletions clang/test/Driver/fuchsia.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,8 @@
// RUN: | FileCheck %s -check-prefix=CHECK-PROFRT-X86_64
// CHECK-PROFRT-X86_64: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK-PROFRT-X86_64: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.profile.a"

// Check that the -X and --no-relax flags are passed to the linker on riscv64
// RUN: %clang --target=riscv64-unknown-fuchsia -mno-relax -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=RISCV64-FLAGS %s
// RISCV64-FLAGS: "-X" "--no-relax"
5 changes: 5 additions & 0 deletions clang/test/Driver/haiku.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@
// RUN: | FileCheck --check-prefix=CHECK-ARM-CPU %s
// CHECK-ARM-CPU: "-target-cpu" "arm1176jzf-s"

// Check that the -X and --no-relax flags are passed to the linker on riscv64
// RUN: %clang --target=riscv64-unknown-haiku -mno-relax -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=RISCV64-FLAGS %s
// RISCV64-FLAGS: "-X" "--no-relax"

// Check passing LTO flags to the linker
// RUN: %clang --target=x86_64-unknown-haiku -flto -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-LTO-FLAGS %s
Expand Down
40 changes: 0 additions & 40 deletions clang/test/Driver/modules-print-library-module-manifest-path.cpp

This file was deleted.

7 changes: 7 additions & 0 deletions clang/test/Driver/netbsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,10 @@
// DRIVER-PASS-INCLUDES: "-cc1" {{.*}}"-resource-dir" "[[RESOURCE:[^"]+]]"
// DRIVER-PASS-INCLUDES-SAME: "-internal-isystem" "[[RESOURCE]]{{/|\\\\}}include"
// DRIVER-PASS-INCLUDES-SAME: {{^}} "-internal-externc-isystem" "{{.*}}/usr/include"

// Check that the -X and --no-relax flags are passed to the linker on riscv
// RUN: %clang --target=riscv32-unknown-netbsd -mno-relax -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=RISCV-FLAGS %s
// RUN: %clang --target=riscv64-unknown-netbsd -mno-relax -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=RISCV-FLAGS %s
// RISCV-FLAGS: "-X" "--no-relax"
8 changes: 4 additions & 4 deletions clang/test/Driver/openbsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@
// UNWIND-TABLES: "-funwind-tables=2"
// NO-UNWIND-TABLES-NOT: "-funwind-tables=2"

// Check that the -X flag is passed to the linker on riscv64
// RUN: %clang --target=riscv64-unknown-openbsd -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-RISCV64-FLAGS %s
// CHECK-RISCV64-FLAGS: "-X"
// Check that the -X and --no-relax flags are passed to the linker on riscv64
// RUN: %clang --target=riscv64-unknown-openbsd -mno-relax -### %s 2>&1 \
// RUN: | FileCheck -check-prefix=RISCV64-FLAGS %s
// RISCV64-FLAGS: "-X" "--no-relax"

// Check passing LTO flags to the linker
// RUN: %clang --target=amd64-unknown-openbsd -flto -### %s 2>&1 \
Expand Down
65 changes: 62 additions & 3 deletions clang/test/InstallAPI/objcclasses.test
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,68 @@
@end

__attribute__((visibility("hidden")))
@interface Hidden
@interface Hidden
@end

__attribute__((visibility("hidden")))
@interface HiddenWithIvars {
@public
char _ivar;
}
@end

__attribute__((objc_exception))
@interface Exception
@end

@interface PublicClass : Visible {
@package
int _internal;
@protected
int _external;
@private
int private;
@public
char _public;
}
@end


//--- Foo.framework/PrivateHeaders/Foo_Private.h
#import <Foo/Foo.h>

@interface ClassWithIvars : Visible {
char _ivar1;
char _ivar2;
@private
int _privateIVar;
@protected
int _externalIVar;
@package
int _internalIVar;
}
@end

@interface Exception () {
@public
char _ivarFromExtension;
@private
int _privateIvarFromExtension;
}
@end


//--- inputs.json.in
{
"headers": [ {
"path" : "DSTROOT/Foo.framework/Headers/Foo.h",
"type" : "public"
}],
},
{
"path" : "DSTROOT/Foo.framework/PrivateHeaders/Foo_Private.h",
"type" : "private"
}
],
"version": "3"
}

Expand All @@ -53,11 +102,21 @@ __attribute__((objc_exception))
{
"data": {
"objc_class": [
"PublicClass",
"Exception",
"Visible"
"Visible",
"ClassWithIvars"
],
"objc_eh_type": [
"Exception"
],
"objc_ivar": [
"Exception._ivarFromExtension",
"ClassWithIvars._ivar2",
"PublicClass._external",
"ClassWithIvars._ivar1",
"ClassWithIvars._externalIVar",
"PublicClass._public"
]
}
}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Parser/cxx-declarator-attribute-crash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s

// expected-error@+5{{brackets are not allowed here}}
// expected-error@+4{{a type specifier is required for all declarations}}
// expected-warning@+3{{unknown attribute 'h' ignored}}
// expected-error@+2{{definition of variable with array type}}
// expected-error@+1{{expected ';'}}
[][[h]]l
841 changes: 404 additions & 437 deletions clang/test/ParserOpenACC/parse-clauses.c

Large diffs are not rendered by default.

21 changes: 8 additions & 13 deletions clang/test/ParserOpenACC/parse-constructs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,19 @@ void func() {
// expected-note@+1{{to match this '('}}
#pragma acc parallel( clause list
for(;;){}
// expected-error@+3{{expected clause-list or newline in OpenACC directive}}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+2{{expected clause-list or newline in OpenACC directive}}
// expected-error@+1{{invalid OpenACC clause 'clause'}}
#pragma acc serial() clause list
for(;;){}
// expected-error@+4{{expected clause-list or newline in OpenACC directive}}
// expected-error@+3{{expected ')'}}
// expected-note@+2{{to match this '('}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+3{{expected clause-list or newline in OpenACC directive}}
// expected-error@+2{{expected ')'}}
// expected-note@+1{{to match this '('}}
#pragma acc serial( clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+1{{invalid OpenACC clause 'clause'}}
#pragma acc serial clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
// expected-warning@+1{{OpenACC construct 'kernels' not yet implemented, pragma ignored}}
// expected-error@+1{{invalid OpenACC clause 'clause'}}
#pragma acc kernels clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
Expand Down Expand Up @@ -93,8 +89,7 @@ void func() {
// expected-error@+1{{invalid OpenACC clause 'invalid'}}
#pragma acc parallel invalid clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'invalid'}}
// expected-warning@+1{{OpenACC construct 'serial' not yet implemented, pragma ignored}}
// expected-error@+1{{invalid OpenACC clause 'invalid'}}
#pragma acc serial invalid clause list
for(;;){}
// expected-error@+2{{invalid OpenACC clause 'clause'}}
Expand Down
9 changes: 9 additions & 0 deletions clang/test/Preprocessor/riscv-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
// CHECK-NOT: __riscv_smepmp {{.*$}}
// CHECK-NOT: __riscv_ssaia {{.*$}}
// CHECK-NOT: __riscv_ssccptr {{.*$}}
// CHECK-NOT: __riscv_sscofpmf {{.*$}}
// CHECK-NOT: __riscv_sscounterenw {{.*$}}
// CHECK-NOT: __riscv_ssstateen {{.*$}}
// CHECK-NOT: __riscv_ssstrict {{.*$}}
Expand Down Expand Up @@ -351,6 +352,14 @@
// RUN: -o - | FileCheck --check-prefix=CHECK-SSCCPTR-EXT %s
// CHECK-SSCCPTR-EXT: __riscv_ssccptr 1000000{{$}}

// RUN: %clang --target=riscv32-unknown-linux-gnu \
// RUN: -march=rv32isscofpmf -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-SSCOFPMF-EXT %s
// RUN: %clang --target=riscv64-unknown-linux-gnu \
// RUN: -march=rv64isscofpmf -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-SSCOFPMF-EXT %s
// CHECK-SSCOFPMF-EXT: __riscv_sscofpmf 1000000{{$}}

// RUN: %clang --target=riscv32-unknown-linux-gnu \
// RUN: -march=rv32isscounterenw -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-SSCOUNTERENW-EXT %s
Expand Down
100 changes: 50 additions & 50 deletions clang/test/Sema/integer-overflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,169 +11,169 @@ uint64_t f0(uint64_t);
uint64_t f1(uint64_t, uint32_t);
uint64_t f2(uint64_t, ...);

static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536'870'912 with type 'int'}}

uint64_t check_integer_overflows(int i) {
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t overflow = 4608 * 1024 * 1024,
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow2 = (uint64_t)(4608 * 1024 * 1024),
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow3 = (uint64_t)(4608 * 1024 * 1024 * i),
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL),
// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024);
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = 4608 * 1024 * 1024;

uint64_t not_overflow = 4608 * 1024 * 1024ULL;
uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 0 ? 0 : 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if (4608 * 1024 * 1024)
return 0;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 1;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 2;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024 * i))
return 3;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL))
return 4;

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)))
return 5;

switch (i) {
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case 4608 * 1024 * 1024:
return 6;
// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 537'919'488 with type 'int'}}
case (uint64_t)(4609 * 1024 * 1024):
return 7;
// expected-error@+1 {{expression is not an integer constant expression}}
case ((uint64_t)(4608 * 1024 * 1024 * i)):
return 8;
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
return 9;
// expected-warning@+2 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+2 2{{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
return 10;
}

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while (4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024 * i));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while (4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024 * i));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));

// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = 4608 * 1024 * 1024;
(uint64_t)(4608 * 1024 * 1024);
i += (uint64_t)(4608 * 1024 * 1024 * i));

// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL);
((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
_Complex long long x = 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__real__ x) = 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__imag__ x) = 4608 * 1024 * 1024;

// expected-warning@+4 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+4 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 {{array index 536870912 is past the end of the array (that has type 'uint64_t[10]' (aka 'unsigned long long[10]'))}}
// expected-note@+1 {{array 'a' declared here}}
uint64_t a[10];
a[4608 * 1024 * 1024] = 1i;

// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t *b;
uint64_t b2 = b[4608 * 1024 * 1024] + 1;

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
(void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1);

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
}

void check_integer_overflows_in_function_calls(void) {
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f0(4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t x = f0(4608 * 1024 * 1024);

// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t (*f0_ptr)(uint64_t) = &f0;
(void)(*f0_ptr)(4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f2(0, f0(4608 * 1024 * 1024));
}
void check_integer_overflows_in_array_size(void) {
int arr[4608 * 1024 * 1024]; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
int arr[4608 * 1024 * 1024]; // expected-warning {{overflow in expression; result is 536'870'912 with type 'int'}}
}

struct s {
Expand Down
9 changes: 5 additions & 4 deletions clang/test/Sema/static-assert.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c11 -Wgnu-folding-constant -fsyntax-only -verify %s
// RUN: %clang_cc1 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms %s
// RUN: %clang_cc1 -std=c99 -pedantic -Wgnu-folding-constant -fsyntax-only -verify=expected,ext %s
// RUN: %clang_cc1 -std=c11 -Wgnu-folding-constant -fsyntax-only -verify=expected,c %s
// RUN: %clang_cc1 -fms-compatibility -Wgnu-folding-constant -DMS -fsyntax-only -verify=expected,ms,c %s
// RUN: %clang_cc1 -std=c99 -pedantic -Wgnu-folding-constant -fsyntax-only -verify=expected,ext,c %s
// RUN: %clang_cc1 -xc++ -std=c++11 -pedantic -fsyntax-only -verify=expected,ext,cxx %s

_Static_assert("foo", "string is nonzero"); // ext-warning {{'_Static_assert' is a C11 extension}}
Expand Down Expand Up @@ -57,7 +57,8 @@ UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; // ext-warning 3 {{'_Static_
typedef UNION(char, short) U3; // expected-error {{static assertion failed due to requirement 'sizeof(char) == sizeof(short)': type size mismatch}} \
// expected-note{{evaluates to '1 == 2'}} \
// ext-warning 3 {{'_Static_assert' is a C11 extension}}
typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \
typedef UNION(float, 0.5f) U4; // c-error {{expected a type}} \
// cxx-error {{type name requires a specifier or qualifier}} \
// ext-warning 3 {{'_Static_assert' is a C11 extension}}

// After defining the assert macro in MS-compatibility mode, we should
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Sema/switch-1.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ int f(int i) {
switch (i) {
case 2147483647 + 2:
#if (__cplusplus <= 199711L) // C or C++03 or earlier modes
// expected-warning@-2 {{overflow in expression; result is -2147483647 with type 'int'}}
// expected-warning@-2 {{overflow in expression; result is -2'147'483'647 with type 'int'}}
#else
// expected-error@-4 {{case value is not a constant expression}} \
// expected-note@-4 {{value 2147483649 is outside the range of representable values of type 'int'}}
Expand All @@ -23,7 +23,7 @@ int f(int i) {
return 2;
case (123456 *789012) + 1:
#if (__cplusplus <= 199711L)
// expected-warning@-2 {{overflow in expression; result is -1375982336 with type 'int'}}
// expected-warning@-2 {{overflow in expression; result is -1'375'982'336 with type 'int'}}
#else
// expected-error@-4 {{case value is not a constant expression}} \
// expected-note@-4 {{value 97408265472 is outside the range of representable values of type 'int'}}
Expand All @@ -47,7 +47,7 @@ int f(int i) {
case 2147483647:
return 0;
}
return (i, 65537) * 65537; // expected-warning {{overflow in expression; result is 131073 with type 'int'}} \
return (i, 65537) * 65537; // expected-warning {{overflow in expression; result is 131'073 with type 'int'}} \
// expected-warning {{left operand of comma operator has no effect}}
}

Expand Down
15 changes: 15 additions & 0 deletions clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,18 @@ namespace GH62224 {
C<> Val; // No error since fwd is defined already.
static_assert(Val.get() == 42);
}

namespace GH80630 {

consteval const char* ce() { return "Hello"; }

auto f2(const char* loc = []( char const* fn )
{ return fn; } ( ce() ) ) {
return loc;
}

auto g() {
return f2();
}

}
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ enum { overflow = 123456 * 234567 };
// expected-warning@-2 {{not an integral constant expression}}
// expected-note@-3 {{value 28958703552 is outside the range of representable values}}
#else
// expected-warning@-5 {{overflow in expression; result is -1106067520 with type 'int'}}
// expected-warning@-5 {{overflow in expression; result is -1'106'067'520 with type 'int'}}
#endif

// FIXME: This is not consistent with the above case.
Expand All @@ -112,7 +112,7 @@ enum NoFold : int { overflow2 = 123456 * 234567 };
// expected-error@-2 {{enumerator value is not a constant expression}}
// expected-note@-3 {{value 28958703552 is outside the range of representable values}}
#else
// expected-warning@-5 {{overflow in expression; result is -1106067520 with type 'int'}}
// expected-warning@-5 {{overflow in expression; result is -1'106'067'520 with type 'int'}}
// expected-warning@-6 {{extension}}
#endif

Expand Down
112 changes: 56 additions & 56 deletions clang/test/SemaCXX/integer-overflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,180 +13,180 @@ uint64_t f0(uint64_t);
uint64_t f1(uint64_t, uint32_t);
uint64_t f2(uint64_t, ...);

static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536'870'912 with type 'int'}}

uint64_t check_integer_overflows(int i) { //expected-note 0+{{declared here}}
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t overflow = 4608 * 1024 * 1024,
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow2 = (uint64_t)(4608 * 1024 * 1024),
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow3 = (uint64_t)(4608 * 1024 * 1024 * i),
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL),
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow5 = static_cast<uint64_t>(4608 * 1024 * 1024),
// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024);
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = static_cast<uint64_t>(4608 * 1024 * 1024);

uint64_t not_overflow = 4608 * 1024 * 1024ULL;
uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 0 ? 0 : 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if (4608 * 1024 * 1024)
return 0;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 1;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if (static_cast<uint64_t>(4608 * 1024 * 1024))
return 1;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 2;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024 * i))
return 3;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL))
return 4;

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)))
return 5;

#if __cplusplus < 201103L
switch (i) {
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case 4608 * 1024 * 1024:
return 6;
// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 537'919'488 with type 'int'}}
case (uint64_t)(4609 * 1024 * 1024):
return 7;
// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 537'919'488 with type 'int'}}
case 1 + static_cast<uint64_t>(4609 * 1024 * 1024):
return 7;
// expected-error@+1 {{expression is not an integral constant expression}}
case ((uint64_t)(4608 * 1024 * 1024 * i)):
return 8;
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
return 9;
// expected-warning@+2 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+2 2{{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
return 10;
}
#endif

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while (4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while (static_cast<uint64_t>(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024 * i));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while (4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while (static_cast<uint64_t>(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024 * i));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));

// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = 4608 * 1024 * 1024;
(uint64_t)(4608 * 1024 * 1024);
i += (uint64_t)(4608 * 1024 * 1024 * i));

// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning@+3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL);
((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))));

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
_Complex long long x = 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__real__ x) = 4608 * 1024 * 1024;

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__imag__ x) = 4608 * 1024 * 1024;

// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t a[10];
a[4608 * 1024 * 1024] = 1;
#if __cplusplus < 201103L
// expected-warning@-2 {{array index 536870912 is past the end of the array (that has type 'uint64_t[10]' (aka 'unsigned long long[10]'))}}
// expected-note@-4 {{array 'a' declared here}}
#endif

// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
}

void check_integer_overflows_in_function_calls() {
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f0(4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t x = f0(4608 * 1024 * 1024);

// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t (*f0_ptr)(uint64_t) = &f0;
(void)(*f0_ptr)(4608 * 1024 * 1024);

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f2(0, f0(4608 * 1024 * 1024));
}

Expand All @@ -211,7 +211,7 @@ namespace EvaluationCrashes {

namespace GH31643 {
void f() {
int a = -(1<<31); // expected-warning {{overflow in expression; result is -2147483648 with type 'int'}}
int a = -(1<<31); // expected-warning {{overflow in expression; result is -2'147'483'648 with type 'int'}}
}
}

Expand All @@ -237,8 +237,8 @@ u_ptr<bool> Wrap(int64_t x) {
int64_t Pass(int64_t x) { return x; }

int m() {
int64_t x = Pass(30 * 24 * 60 * 59 * 1000); // expected-warning {{overflow in expression; result is -1746167296 with type 'int'}}
auto r = Wrap(Pass(30 * 24 * 60 * 59 * 1000)); // expected-warning {{overflow in expression; result is -1746167296 with type 'int'}}
int64_t x = Pass(30 * 24 * 60 * 59 * 1000); // expected-warning {{overflow in expression; result is -1'746'167'296 with type 'int'}}
auto r = Wrap(Pass(30 * 24 * 60 * 59 * 1000)); // expected-warning {{overflow in expression; result is -1'746'167'296 with type 'int'}}
return 0;
}
}
Expand Down
18 changes: 18 additions & 0 deletions clang/test/SemaCXX/source_location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,3 +832,21 @@ void test() {
}

}

namespace GH80630 {

#define GH80630_LAMBDA \
[]( char const* fn ) { \
static constexpr std::source_location loc = std::source_location::current(); \
return &loc; \
}( std::source_location::current().function() )

auto f( std::source_location const* loc = GH80630_LAMBDA ) {
return loc;
}

auto g() {
return f();
}

}
3 changes: 3 additions & 0 deletions clang/test/SemaCXX/type-traits-nonobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
static_assert(!__is_pod(void), "");
static_assert(!__is_pod(int&), "");
static_assert(!__is_pod(int()), "");
static_assert(!__is_pod(int()&), "");

static_assert(!__is_trivially_copyable(void), "");
static_assert(!__is_trivially_copyable(int&), "");
static_assert(!__is_trivially_copyable(int()), "");
static_assert(!__is_trivially_copyable(int()&), "");

static_assert(!__is_trivially_relocatable(void), "");
static_assert(!__is_trivially_relocatable(int&), "");
static_assert(!__is_trivially_relocatable(int()), "");
static_assert(!__is_trivially_relocatable(int()&), "");
15 changes: 15 additions & 0 deletions clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wno-unused -Wunsequenced -verify %s

struct A {
int x, y;
};

void test() {
int a = 0;

A agg1( a++, a++ ); // no warning
A agg2( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}}

int arr1[]( a++, a++ ); // no warning
int arr2[]( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}}
}
4 changes: 2 additions & 2 deletions clang/test/SemaObjC/integer-overflow.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ - (int)add:(int)a with:(int)b {
}

- (void)testIntegerOverflows {
// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)[self add:0 with:4608 * 1024 * 1024];

// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)[self add:0 with:[self add:4608 * 1024 * 1024 with:0]];
}
@end
2 changes: 1 addition & 1 deletion clang/test/SemaObjC/objc-literal-nsnumber.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ int main(void) {
@-five; // expected-error{{@- must be followed by a number to form an NSNumber object}}
@+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}}
NSNumber *av = @(1391126400000);
NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443003904 with type 'int'}}
NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443'003'904 with type 'int'}}
NSNumber *cv = @(big * thousand);
}

Expand Down
50 changes: 50 additions & 0 deletions clang/test/SemaOpenACC/compute-construct-ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ void NormalFunc() {
#pragma acc parallel
{}
}
// FIXME: Add a test once we have clauses for this.
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
#pragma acc serial
{
#pragma acc serial
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
#pragma acc serial
{}
}
// FIXME: Add a test once we have clauses for this.
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
#pragma acc kernels
{
#pragma acc kernels
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
#pragma acc kernels
{}
}
}

template<typename T>
Expand All @@ -24,6 +48,16 @@ void TemplFunc() {
typename T::type I;
}

#pragma acc serial
{
typename T::type I;
}

#pragma acc kernels
{
typename T::type I;
}

// CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc
// CHECK-NEXT: TemplateTypeParmDecl

Expand All @@ -34,6 +68,14 @@ void TemplFunc() {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename T::type'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename T::type'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename T::type'

// Check instantiation.
// CHECK-LABEL: FunctionDecl{{.*}} used TemplFunc 'void ()' implicit_instantiation
Expand All @@ -45,6 +87,14 @@ void TemplFunc() {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}serial
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int'
// CHECK-NEXT: OpenACCComputeConstruct {{.*}}kernels
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int'
}

struct S {
Expand Down
66 changes: 66 additions & 0 deletions clang/test/SemaOpenACC/no-branch-in-out.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ void BreakContinue() {
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
}

#pragma acc serial
for(int i = 0; i < 5; ++i) {
if (i > 1)
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
}

#pragma acc kernels
for(int i = 0; i < 5; ++i) {
if (i > 1)
break; // expected-error{{invalid branch out of OpenACC Compute Construct}}
}

#pragma acc parallel
switch(j) {
case 1:
Expand Down Expand Up @@ -99,6 +111,16 @@ void Return() {
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
}

#pragma acc serial
{
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
}

#pragma acc kernels
{
return;// expected-error{{invalid return out of OpenACC Compute Construct}}
}

#pragma acc parallel
{
{
Expand Down Expand Up @@ -255,6 +277,34 @@ LABEL13:{}
LABEL14:{}
({goto LABEL14;});
}



({goto LABEL15;});// expected-error{{cannot jump from this goto statement to its label}}
#pragma acc serial// expected-note{{invalid branch into OpenACC Compute Construct}}
{
LABEL15:{}
}

LABEL16:{}
#pragma acc serial// expected-note{{invalid branch out of OpenACC Compute Construct}}
{
({goto LABEL16;});// expected-error{{cannot jump from this goto statement to its label}}
}


({goto LABEL17;});// expected-error{{cannot jump from this goto statement to its label}}
#pragma acc kernels// expected-note{{invalid branch into OpenACC Compute Construct}}
{
LABEL17:{}
}

LABEL18:{}
#pragma acc kernels// expected-note{{invalid branch out of OpenACC Compute Construct}}
{
({goto LABEL18;});// expected-error{{cannot jump from this goto statement to its label}}
}

}

void IndirectGoto1() {
Expand Down Expand Up @@ -329,11 +379,27 @@ void DuffsDevice() {
}
}

switch (j) {
#pragma acc kernels
for(int i =0; i < 5; ++i) {
default: // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}

switch (j) {
#pragma acc parallel
for(int i =0; i < 5; ++i) {
case 'a' ... 'z': // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}

switch (j) {
#pragma acc serial
for(int i =0; i < 5; ++i) {
case 'a' ... 'z': // expected-error{{invalid branch into OpenACC Compute Construct}}
{}
}
}
}
11 changes: 11 additions & 0 deletions clang/test/SemaOpenACC/no-branch-in-out.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ void Exceptions() {
throw; // expected-error{{invalid throw out of OpenACC Compute Construct}}
}

#pragma acc serial
for(int i = 0; i < 5; ++i) {
throw; // expected-error{{invalid throw out of OpenACC Compute Construct}}
}

#pragma acc kernels
for(int i = 0; i < 5; ++i) {
throw; // expected-error{{invalid throw out of OpenACC Compute Construct}}
}


#pragma acc parallel
for(int i = 0; i < 5; ++i) {
try {
Expand Down
8 changes: 7 additions & 1 deletion clang/test/SemaOpenACC/parallel-assoc-stmt-inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ template<typename T>
void Func() {
#pragma acc parallel
typename T::type I; //#ILOC
#pragma acc serial
typename T::type IS; //#ILOCSERIAL
#pragma acc kernels
typename T::type IK; //#ILOCKERNELS
}

struct S {
Expand All @@ -13,6 +17,8 @@ struct S {
void use() {
Func<S>();
// expected-error@#ILOC{{type 'int' cannot be used prior to '::' because it has no members}}
// expected-note@+1{{in instantiation of function template specialization 'Func<int>' requested here}}
// expected-note@+3{{in instantiation of function template specialization 'Func<int>' requested here}}
// expected-error@#ILOCSERIAL{{type 'int' cannot be used prior to '::' because it has no members}}
// expected-error@#ILOCKERNELS{{type 'int' cannot be used prior to '::' because it has no members}}
Func<int>();
}
27 changes: 27 additions & 0 deletions clang/test/SemaOpenACC/parallel-loc-and-stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,32 @@
// expected-error@+1{{OpenACC construct 'parallel' cannot be used here; it can only be used in a statement context}}
#pragma acc parallel

// expected-error@+1{{OpenACC construct 'serial' cannot be used here; it can only be used in a statement context}}
#pragma acc serial

// expected-error@+1{{OpenACC construct 'kernels' cannot be used here; it can only be used in a statement context}}
#pragma acc kernels

// expected-error@+1{{OpenACC construct 'parallel' cannot be used here; it can only be used in a statement context}}
#pragma acc parallel
int foo;
// expected-error@+1{{OpenACC construct 'serial' cannot be used here; it can only be used in a statement context}}
#pragma acc serial
int foo2;
// expected-error@+1{{OpenACC construct 'kernels' cannot be used here; it can only be used in a statement context}}
#pragma acc kernels
int foo3;

struct S {
// expected-error@+1{{OpenACC construct 'parallel' cannot be used here; it can only be used in a statement context}}
#pragma acc parallel
int foo;
// expected-error@+1{{OpenACC construct 'serial' cannot be used here; it can only be used in a statement context}}
#pragma acc serial
int foo2;
// expected-error@+1{{OpenACC construct 'kernels' cannot be used here; it can only be used in a statement context}}
#pragma acc kernels
int foo3;
};

void func() {
Expand All @@ -31,6 +49,15 @@ void func() {
#pragma acc parallel
}

{
// expected-error@+2{{expected statement}}
#pragma acc serial
}
{
// expected-error@+2{{expected statement}}
#pragma acc kernels
}

#pragma acc parallel
while(0){}

Expand Down
30 changes: 30 additions & 0 deletions clang/test/SemaTemplate/unqual-unresolved-using-value.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s

template<typename T>
struct A : T {
using T::f;
using T::g;
using T::h;

void f();
void g();

void i() {
f<int>();
g<int>(); // expected-error{{no member named 'g' in 'A<B>'}}
h<int>(); // expected-error{{expected '(' for function-style cast or type construction}}
// expected-error@-1{{expected expression}}
}
};

struct B {
template<typename T>
void f();

void g();

template<typename T>
void h();
};

template struct A<B>; // expected-note{{in instantiation of member function 'A<B>::i' requested here}}
115 changes: 115 additions & 0 deletions clang/test/TableGen/target-builtins-prototype-parser.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// RUN: clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins | FileCheck %s
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_LANES 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_LANES
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_COMMA 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_COMMA
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_TYPE 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_TYPE
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_A 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_A
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_B 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_B
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_C 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_C
// RUN: not clang-tblgen -I %p/../../../clang/include/ %s --gen-clang-builtins -DERROR_EXPECTED_D 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_D

include "clang/Basic/BuiltinsBase.td"

def : Builtin {
// CHECK: BUILTIN(__builtin_01, "E8idE4b", "")
let Prototype = "_ExtVector<8,int>(double, _ExtVector<4, bool>)";
let Spellings = ["__builtin_01"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_02, "E8UiE4s", "")
let Prototype = "_ExtVector<8,unsigned int>(_ExtVector<4, short>)";
let Spellings = ["__builtin_02"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_03, "di", "")
let Prototype = "double(int)";
let Spellings = ["__builtin_03"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_04, "diIUi", "")
let Prototype = "double(int, _Constant unsigned int)";
let Spellings = ["__builtin_04"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_05, "v&v&", "")
let Prototype = "void&(void&)";
let Spellings = ["__builtin_05"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_06, "v*v*cC*.", "")
let Prototype = "void*(void*, char const*, ...)";
let Spellings = ["__builtin_06"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_07, "E8iE4dE4b.", "")
let Prototype = "_ExtVector<8, int>(_ExtVector<4,double>, _ExtVector<4, bool>, ...)";
let Spellings = ["__builtin_07"];
}

def : Builtin {
// CHECK: BUILTIN(__builtin_08, "di*R", "")
let Prototype = "double(int * restrict)";
let Spellings = ["__builtin_08"];
}

#ifdef ERROR_EXPECTED_LANES
def : Builtin {
// ERROR_EXPECTED_LANES: :[[# @LINE + 1]]:7: error: Expected number of lanes after '_ExtVector<'
let Prototype = "_ExtVector<int>(double)";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

#ifdef ERROR_EXPECTED_COMMA
def : Builtin {
// ERROR_EXPECTED_COMMA: :[[# @LINE + 1]]:7: error: Expected ',' after number of lanes in '_ExtVector<'
let Prototype = "_ExtVector<8 int>(double)";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

#ifdef ERROR_EXPECTED_TYPE
def : Builtin {
// ERROR_EXPECTED_TYPE: :[[# @LINE + 1]]:7: error: Expected '>' after scalar type in '_ExtVector<N, type>'
let Prototype = "_ExtVector<8, int (double)";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

#ifdef ERROR_EXPECTED_A
def : Builtin {
// ERROR_EXPECTED_A: :[[# @LINE + 1]]:7: error: Expected '<' after '_ExtVector'
let Prototype = "_ExtVector(8, int) (double)";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

#ifdef ERROR_EXPECTED_B
def : Builtin {
// ERROR_EXPECTED_B: :[[# @LINE + 1]]:7: error: Expected '<' after '_ExtVector'
let Prototype = "double(_ExtVector(8, int))";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

#ifdef ERROR_EXPECTED_C
def : Builtin {
// ERROR_EXPECTED_C: :[[# @LINE + 1]]:7: error: Unknown Type: _EtxVector<8, int>
let Prototype = "_EtxVector<8, int>(void)";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

#ifdef ERROR_EXPECTED_D
def : Builtin {
// ERROR_EXPECTED_D: :[[# @LINE + 1]]:7: error: Expected number of lanes after '_ExtVector<'
let Prototype = "_ExtVector<>(void)";
let Spellings = ["__builtin_test_use_clang_extended_vectors"];
}
#endif

66 changes: 63 additions & 3 deletions clang/utils/TableGen/ClangBuiltinsEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,47 @@ class PrototypeParser {
if (!Prototype.ends_with(")"))
PrintFatalError(Loc, "Expected closing brace at end of prototype");
Prototype = Prototype.drop_back();
for (auto T = Prototype.split(','); !T.first.empty();
Prototype = T.second, T = Prototype.split(','))
ParseType(T.first);

// Look through the input parameters.
const size_t end = Prototype.size();
for (size_t I = 0; I != end;) {
const StringRef Current = Prototype.substr(I, end);
// Skip any leading space or commas
if (Current.starts_with(" ") || Current.starts_with(",")) {
++I;
continue;
}

// Check if we are in _ExtVector. We do this first because
// extended vectors are written in template form with the syntax
// _ExtVector< ..., ...>, so we need to make sure we are not
// detecting the comma of the template class as a separator for
// the parameters of the prototype. Note: the assumption is that
// we cannot have nested _ExtVector.
if (Current.starts_with("_ExtVector<")) {
const size_t EndTemplate = Current.find('>', 0);
ParseType(Current.substr(0, EndTemplate + 1));
// Move the prototype beyond _ExtVector<...>
I += EndTemplate + 1;
continue;
}

// We know that we are past _ExtVector, therefore the first seen
// comma is the boundary of a parameter in the prototype.
if (size_t CommaPos = Current.find(',', 0)) {
if (CommaPos != StringRef::npos) {
StringRef T = Current.substr(0, CommaPos);
ParseType(T);
// Move the prototype beyond the comma.
I += CommaPos + 1;
continue;
}
}

// No more commas, parse final parameter.
ParseType(Current);
I = end;
}
}

void ParseType(StringRef T) {
Expand Down Expand Up @@ -85,6 +123,28 @@ class PrototypeParser {
if (Substitution.empty())
PrintFatalError(Loc, "Not a template");
ParseType(Substitution);
} else if (T.consume_front("_ExtVector")) {
// Clang extended vector types are mangled as follows:
//
// '_ExtVector<' <lanes> ',' <scalar type> '>'

// Before parsing T(=<scalar type>), make sure the syntax of
// `_ExtVector<N, T>` is correct...
if (!T.consume_front("<"))
PrintFatalError(Loc, "Expected '<' after '_ExtVector'");
unsigned long long Lanes;
if (llvm::consumeUnsignedInteger(T, 10, Lanes))
PrintFatalError(Loc, "Expected number of lanes after '_ExtVector<'");
Type += "E" + std::to_string(Lanes);
if (!T.consume_front(","))
PrintFatalError(Loc,
"Expected ',' after number of lanes in '_ExtVector<'");
if (!T.consume_back(">"))
PrintFatalError(
Loc, "Expected '>' after scalar type in '_ExtVector<N, type>'");

// ...all good, we can check if we have a valid `<scalar type>`.
ParseType(T);
} else {
auto ReturnTypeVal = StringSwitch<std::string>(T)
.Case("__builtin_va_list_ref", "A")
Expand Down
15 changes: 15 additions & 0 deletions flang/docs/Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,21 @@ end
`INDEX` include an optional `BACK=` argument, but it doesn't actually
work.

* Allocatable components of array and structure constructors are deallocated
after use without calling final subroutines.
The standard does not specify when and how deallocation of array and structure
constructors allocatable components should happen. All compilers free the
memory after use, but the behavior when the allocatable component is a derived
type with finalization differ, especially when dealing with nested array and
structure constructors expressions. Some compilers call final routine for the
allocatable components of each constructor sub-expressions, some call it only
for the allocatable component of the top level constructor, and some only
deallocate the memory. Deallocating only the memory offers the most
flexibility when lowering such expressions, and it is not clear finalization
is desirable in such context (Fortran interop 1.6.2 in F2018 standards require
array and structure constructors not to be finalized, so it also makes sense
not to finalize their allocatable components when releasing their storage).

## De Facto Standard Features

* `EXTENDS_TYPE_OF()` returns `.TRUE.` if both of its arguments have the
Expand Down
75 changes: 58 additions & 17 deletions flang/lib/Lower/ConvertCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,18 @@ mlir::Value static getZeroLowerBounds(mlir::Location loc,
return builder.genShift(loc, lowerBounds);
}

static bool
isSimplyContiguous(const Fortran::evaluate::ActualArgument &arg,
Fortran::evaluate::FoldingContext &foldingContext) {
if (const auto *expr = arg.UnwrapExpr())
return Fortran::evaluate::IsSimplyContiguous(*expr, foldingContext);
const Fortran::semantics::Symbol *sym = arg.GetAssumedTypeDummy();
assert(sym &&
"expect ActualArguments to be expression or assumed-type symbols");
return sym->Rank() == 0 ||
Fortran::evaluate::IsSimplyContiguous(*sym, foldingContext);
}

/// When dummy is not ALLOCATABLE, POINTER and is not passed in register,
/// prepare the actual argument according to the interface. Do as needed:
/// - address element if this is an array argument in an elemental call.
Expand All @@ -985,7 +997,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
const Fortran::lower::PreparedActualArgument &preparedActual,
mlir::Type dummyType,
const Fortran::lower::CallerInterface::PassedEntity &arg,
const Fortran::lower::SomeExpr &expr, CallContext &callContext) {
CallContext &callContext) {

Fortran::evaluate::FoldingContext &foldingContext =
callContext.converter.getFoldingContext();
Expand Down Expand Up @@ -1036,7 +1048,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
const bool mustDoCopyInOut =
actual.isArray() && arg.mustBeMadeContiguous() &&
(passingPolymorphicToNonPolymorphic ||
!Fortran::evaluate::IsSimplyContiguous(expr, foldingContext));
!isSimplyContiguous(*arg.entity, foldingContext));

const bool actualIsAssumedRank = actual.isAssumedRank();
// Create dummy type with actual argument rank when the dummy is an assumed
Expand Down Expand Up @@ -1114,9 +1126,11 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
arg.mayBeModifiedByCall() ? copyIn.getVar() : mlir::Value{});
}
} else {
const Fortran::lower::SomeExpr *expr = arg.entity->UnwrapExpr();
assert(expr && "expression actual argument cannot be an assumed type");
// The actual is an expression value, place it into a temporary
// and register the temporary destruction after the call.
mlir::Type storageType = callContext.converter.genType(expr);
mlir::Type storageType = callContext.converter.genType(*expr);
mlir::NamedAttribute byRefAttr = fir::getAdaptToByRefAttr(builder);
hlfir::AssociateOp associate = hlfir::genAssociateExpr(
loc, builder, entity, storageType, "", byRefAttr);
Expand Down Expand Up @@ -1202,7 +1216,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
if (auto baseBoxDummy = mlir::dyn_cast<fir::BaseBoxType>(dummyType))
if (baseBoxDummy.isAssumedRank())
if (const Fortran::semantics::Symbol *sym =
Fortran::evaluate::UnwrapWholeSymbolDataRef(expr))
Fortran::evaluate::UnwrapWholeSymbolDataRef(*arg.entity))
if (Fortran::semantics::IsAssumedSizeArray(sym->GetUltimate()))
TODO(loc, "passing assumed-size to assumed-rank array");

Expand All @@ -1224,10 +1238,10 @@ static PreparedDummyArgument prepareUserCallActualArgument(
const Fortran::lower::PreparedActualArgument &preparedActual,
mlir::Type dummyType,
const Fortran::lower::CallerInterface::PassedEntity &arg,
const Fortran::lower::SomeExpr &expr, CallContext &callContext) {
CallContext &callContext) {
if (!preparedActual.handleDynamicOptional())
return preparePresentUserCallActualArgument(
loc, builder, preparedActual, dummyType, arg, expr, callContext);
return preparePresentUserCallActualArgument(loc, builder, preparedActual,
dummyType, arg, callContext);

// Conditional dummy argument preparation. The actual may be absent
// at runtime, causing any addressing, copy, and packaging to have
Expand All @@ -1249,7 +1263,7 @@ static PreparedDummyArgument prepareUserCallActualArgument(
builder.setInsertionPointToStart(preparationBlock);
PreparedDummyArgument unconditionalDummy =
preparePresentUserCallActualArgument(loc, builder, preparedActual,
dummyType, arg, expr, callContext);
dummyType, arg, callContext);
builder.restoreInsertionPoint(insertPt);

// TODO: when forwarding an optional to an optional of the same kind
Expand Down Expand Up @@ -1291,10 +1305,11 @@ static PreparedDummyArgument prepareProcedurePointerActualArgument(
const Fortran::lower::PreparedActualArgument &preparedActual,
mlir::Type dummyType,
const Fortran::lower::CallerInterface::PassedEntity &arg,
const Fortran::lower::SomeExpr &expr, CallContext &callContext) {
CallContext &callContext) {

// NULL() actual to procedure pointer dummy
if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(expr) &&
if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
*arg.entity) &&
fir::isBoxProcAddressType(dummyType)) {
auto boxTy{Fortran::lower::getUntypedBoxProcType(builder.getContext())};
auto tempBoxProc{builder.createTemporary(loc, boxTy)};
Expand Down Expand Up @@ -1335,9 +1350,6 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
caller.placeInput(arg, builder.genAbsentOp(loc, argTy));
continue;
}
const auto *expr = arg.entity->UnwrapExpr();
if (!expr)
TODO(loc, "assumed type actual argument");

switch (arg.passBy) {
case PassBy::Value: {
Expand Down Expand Up @@ -1380,15 +1392,15 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
case PassBy::BaseAddress:
case PassBy::BoxChar: {
PreparedDummyArgument preparedDummy = prepareUserCallActualArgument(
loc, builder, *preparedActual, argTy, arg, *expr, callContext);
loc, builder, *preparedActual, argTy, arg, callContext);
callCleanUps.append(preparedDummy.cleanups.rbegin(),
preparedDummy.cleanups.rend());
caller.placeInput(arg, preparedDummy.dummy);
} break;
case PassBy::BoxProcRef: {
PreparedDummyArgument preparedDummy =
prepareProcedurePointerActualArgument(loc, builder, *preparedActual,
argTy, arg, *expr, callContext);
argTy, arg, callContext);
callCleanUps.append(preparedDummy.cleanups.rbegin(),
preparedDummy.cleanups.rend());
caller.placeInput(arg, preparedDummy.dummy);
Expand All @@ -1408,6 +1420,9 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
caller.placeInput(arg, actual);
} break;
case PassBy::MutableBox: {
const Fortran::lower::SomeExpr *expr = arg.entity->UnwrapExpr();
// C709 and C710.
assert(expr && "cannot pass TYPE(*) to POINTER or ALLOCATABLE");
hlfir::Entity actual = preparedActual->getActual(loc, builder);
if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
*expr)) {
Expand Down Expand Up @@ -2405,8 +2420,34 @@ genProcedureRef(CallContext &callContext) {
caller.getPassedArguments())
if (const auto *actual = arg.entity) {
const auto *expr = actual->UnwrapExpr();
if (!expr)
TODO(loc, "assumed type actual argument");
if (!expr) {
// TYPE(*) actual argument.
const Fortran::evaluate::Symbol *assumedTypeSym =
actual->GetAssumedTypeDummy();
if (!assumedTypeSym)
fir::emitFatalError(
loc, "expected assumed-type symbol as actual argument");
std::optional<fir::FortranVariableOpInterface> var =
callContext.symMap.lookupVariableDefinition(*assumedTypeSym);
if (!var)
fir::emitFatalError(loc, "assumed-type symbol was not lowered");
hlfir::Entity actual{*var};
std::optional<mlir::Value> isPresent;
if (arg.isOptional()) {
// Passing an optional TYPE(*) to an optional TYPE(*). Note that
// TYPE(*) cannot be ALLOCATABLE/POINTER (C709) so there is no
// need to cover the case of passing an ALLOCATABLE/POINTER to an
// OPTIONAL.
fir::FirOpBuilder &builder = callContext.getBuilder();
isPresent =
builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), actual)
.getResult();
}
loweredActuals.push_back(Fortran::lower::PreparedActualArgument{
hlfir::Entity{*var}, isPresent});
continue;
}

if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
*expr)) {
if ((arg.passBy !=
Expand Down
10 changes: 10 additions & 0 deletions flang/lib/Lower/ConvertExprToHLFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,16 @@ class HlfirBuilder {
builder.genIfThen(loc, isAlloc).genThen(genAssign).end();
}

if (fir::isRecordWithAllocatableMember(recTy)) {
// Deallocate allocatable components without calling final subroutines.
// The Fortran 2018 section 9.7.3.2 about deallocation is not ruling
// about the fate of allocatable components of structure constructors,
// and there is no behavior consensus in other compilers.
fir::FirOpBuilder *bldr = &builder;
getStmtCtx().attachCleanup([=]() {
fir::runtime::genDerivedTypeDestroyWithoutFinalization(*bldr, loc, box);
});
}
return varOp;
}

Expand Down
9 changes: 7 additions & 2 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1810,7 +1810,11 @@ genOMP(Fortran::lower::AbstractConverter &converter,
/*outerCombined=*/false);
break;
case llvm::omp::Directive::OMPD_workshare:
TODO(currentLocation, "Workshare construct");
// FIXME: Workshare is not a commonly used OpenMP construct, an
// implementation for this feature will come later. For the codes
// that use this construct, add a single construct for now.
genSingleOp(converter, semaCtx, eval, /*genNested=*/true, currentLocation,
beginClauseList, endClauseList);
break;
default:
singleDirective = false;
Expand Down Expand Up @@ -1845,7 +1849,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
}
if ((llvm::omp::workShareSet & llvm::omp::blockConstructSet)
.test(directive.v)) {
TODO(currentLocation, "Workshare construct");
genSingleOp(converter, semaCtx, eval, /*genNested=*/false, currentLocation,
beginClauseList, endClauseList);
combinedDirective = true;
}
if (!combinedDirective)
Expand Down
2 changes: 0 additions & 2 deletions flang/test/Fir/memory-allocation-opt.fir
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// RUN: fir-opt --memory-allocation-opt="dynamic-array-on-heap=true maximum-array-alloc-size=1024" %s | FileCheck %s
// FIXME: started crashing on windows https://github.com/llvm/llvm-project/issues/83534
// UNSUPPORTED: system-windows

// Test for size of array being too big.

Expand Down
226 changes: 226 additions & 0 deletions flang/test/HLFIR/assumed-type-actual-args.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
! Test lowering to FIR of actual arguments that are assumed type
! variables (Fortran 2018 7.3.2.2 point 3).
! RUN: bbc --polymorphic-type -emit-hlfir -o - %s | FileCheck %s

subroutine test1(x)
interface
subroutine s1(x)
type(*) :: x
end subroutine
end interface
type(*) :: x
call s1(x)
end subroutine

subroutine test2(x)
interface
subroutine s2(x)
type(*) :: x(*)
end subroutine
end interface
type(*) :: x(*)
call s2(x)
end subroutine

subroutine test3(x)
interface
subroutine s3(x)
type(*) :: x(:)
end subroutine
end interface
type(*) :: x(:)
call s3(x)
end subroutine

subroutine test4(x)
interface
subroutine s4(x)
type(*) :: x(*)
end subroutine
end interface
type(*) :: x(:)
call s4(x)
end subroutine

subroutine test3b(x)
interface
subroutine s3b(x)
type(*), optional, contiguous :: x(:)
end subroutine
end interface
type(*), optional :: x(:)
call s3b(x)
end subroutine

subroutine test4b(x)
interface
subroutine s4b(x)
type(*), optional :: x(*)
end subroutine
end interface
type(*), optional :: x(:)
call s4b(x)
end subroutine

subroutine test4c(x)
interface
subroutine s4c(x)
type(*), optional :: x(*)
end subroutine
end interface
type(*), contiguous, optional :: x(:)
call s4c(x)
end subroutine

subroutine test4d(x)
interface
subroutine s4d(x)
type(*) :: x(*)
end subroutine
end interface
type(*), contiguous :: x(:)
call s4d(x)
end subroutine

subroutine test5(x)
interface
subroutine s5(x)
type(*) :: x(..)
end subroutine
end interface
type(*) :: x(:)
call s5(x)
end subroutine

subroutine test5b(x)
interface
subroutine s5b(x)
type(*), optional, contiguous :: x(..)
end subroutine
end interface
type(*), optional :: x(:)
call s5b(x)
end subroutine

! CHECK-LABEL: func.func @_QPtest1(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<none> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest1Ex"} : (!fir.ref<none>) -> (!fir.ref<none>, !fir.ref<none>)
! CHECK: fir.call @_QPs1(%[[VAL_1]]#1) fastmath<contract> : (!fir.ref<none>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest2(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = arith.constant -1 : index
! CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.array<?xnone>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xnone>>, !fir.ref<!fir.array<?xnone>>)
! CHECK: fir.call @_QPs2(%[[VAL_3]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest3(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: fir.call @_QPs3(%[[VAL_1]]#0) fastmath<contract> : (!fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest4(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: fir.call @_QPs4(%[[VAL_3]]) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest3b(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x", fir.optional}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest3bEx"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
! CHECK: fir.result %[[VAL_4]]#0, %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: } else {
! CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_7:.*]] = arith.constant false
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: fir.result %[[VAL_5]], %[[VAL_6]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: }
! CHECK: fir.call @_QPs3b(%[[VAL_9:.*]]#0) fastmath<contract> : (!fir.box<!fir.array<?xnone>>) -> ()
! CHECK: hlfir.copy_out %[[VAL_9]]#1, %[[VAL_9]]#2 to %[[VAL_9]]#3 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest4b(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x", fir.optional}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest4bEx"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.ref<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: fir.result %[[VAL_5]], %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.ref<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: } else {
! CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<!fir.array<?xnone>>
! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_8:.*]] = arith.constant false
! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: fir.result %[[VAL_6]], %[[VAL_7]], %[[VAL_8]], %[[VAL_9]] : !fir.ref<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: }
! CHECK: fir.call @_QPs4b(%[[VAL_10:.*]]#0) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
! CHECK: hlfir.copy_out %[[VAL_10]]#1, %[[VAL_10]]#2 to %[[VAL_10]]#3 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest4c(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x", fir.contiguous, fir.optional}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<contiguous, optional>, uniq_name = "_QFtest4cEx"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
! CHECK: %[[VAL_3:.*]] = fir.if %[[VAL_2]] -> (!fir.ref<!fir.array<?xnone>>) {
! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_1]]#1 : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: fir.result %[[VAL_4]] : !fir.ref<!fir.array<?xnone>>
! CHECK: } else {
! CHECK: %[[VAL_5:.*]] = fir.absent !fir.ref<!fir.array<?xnone>>
! CHECK: fir.result %[[VAL_5]] : !fir.ref<!fir.array<?xnone>>
! CHECK: }
! CHECK: fir.call @_QPs4c(%[[VAL_3]]) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest4d(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x", fir.contiguous}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<contiguous>, uniq_name = "_QFtest4dEx"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#1 : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: fir.call @_QPs4d(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest5(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.box<!fir.array<*:none>>
! CHECK: fir.call @_QPs5(%[[VAL_2]]) fastmath<contract> : (!fir.box<!fir.array<*:none>>) -> ()
! CHECK: return
! CHECK: }

! CHECK-LABEL: func.func @_QPtest5b(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x", fir.optional}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest5bEx"} : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
! CHECK: fir.result %[[VAL_4]]#0, %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: } else {
! CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_7:.*]] = arith.constant false
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: fir.result %[[VAL_5]], %[[VAL_6]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: }
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_10:.*]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.box<!fir.array<*:none>>
! CHECK: fir.call @_QPs5b(%[[VAL_9]]) fastmath<contract> : (!fir.box<!fir.array<*:none>>) -> ()
! CHECK: hlfir.copy_out %[[VAL_10]]#1, %[[VAL_10]]#2 to %[[VAL_10]]#3 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }
12 changes: 12 additions & 0 deletions flang/test/Lower/HLFIR/structure-constructor.f90
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ end subroutine test4
! CHECK: hlfir.assign %[[VAL_26]] to %[[VAL_20]] realloc keep_lhs_len temporary_lhs : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
! CHECK: }
! CHECK: hlfir.assign %[[VAL_12]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_27]]
! CHECK: return
! CHECK: }

Expand Down Expand Up @@ -201,6 +203,8 @@ end subroutine test5
! CHECK: hlfir.assign %[[VAL_24]] to %[[VAL_18]] realloc temporary_lhs : !fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
! CHECK: }
! CHECK: hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.box<none>
! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_24]]
! CHECK: return
! CHECK: }

Expand Down Expand Up @@ -291,6 +295,10 @@ end subroutine test6
! CHECK: %[[VAL_70:.*]] = hlfir.as_expr %[[VAL_48]]#0 move %[[VAL_69]] : (!fir.heap<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>, i1) -> !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
! CHECK: hlfir.assign %[[VAL_70]] to %[[VAL_44]] temporary_lhs : !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>
! CHECK: hlfir.assign %[[VAL_20]]#0 to %[[VAL_12]]#0 : !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>
! CHECK: %[[VAL_71:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> !fir.box<none>
! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_71]]
! CHECK: %[[VAL_72:.*]] = fir.convert %[[VAL_29]] : (!fir.box<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.box<none>
! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_72]]
! CHECK: return
! CHECK: }

Expand Down Expand Up @@ -375,6 +383,8 @@ end subroutine test8
! CHECK: hlfir.assign %[[VAL_29]] to %[[VAL_22]] realloc keep_lhs_len temporary_lhs : !fir.heap<!fir.char<1,12>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
! CHECK: }
! CHECK: hlfir.assign %[[VAL_14]]#0 to %[[VAL_2]]#0 : !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>
! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.box<none>
! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_30]]
! CHECK: return
! CHECK: }

Expand Down Expand Up @@ -410,6 +420,8 @@ end subroutine test9
! CHECK: %[[VAL_20:.*]] = hlfir.designate %[[VAL_12]]#0{"c"} typeparams %[[VAL_19]] {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
! CHECK: hlfir.assign %[[VAL_11]]#0 to %[[VAL_20]] realloc keep_lhs_len temporary_lhs : !fir.ref<!fir.char<1,12>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
! CHECK: hlfir.assign %[[VAL_12]]#0 to %[[VAL_2]]#0 : !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.box<none>
! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_21]]
! CHECK: return
! CHECK: }

Expand Down
42 changes: 42 additions & 0 deletions flang/test/Lower/OpenMP/workshare.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s

!CHECK-LABEL: func @_QPsb1
subroutine sb1(arr)
integer :: arr(:)
!CHECK: omp.parallel {
!$omp parallel
!CHECK: omp.single {
!$omp workshare
arr = 0
!$omp end workshare
!CHECK: }
!$omp end parallel
!CHECK: }
end subroutine

!CHECK-LABEL: func @_QPsb2
subroutine sb2(arr)
integer :: arr(:)
!CHECK: omp.parallel {
!$omp parallel
!CHECK: omp.single nowait {
!$omp workshare
arr = 0
!$omp end workshare nowait
!CHECK: }
!$omp end parallel
!CHECK: }
end subroutine

!CHECK-LABEL: func @_QPsb3
subroutine sb3(arr)
integer :: arr(:)
!CHECK: omp.parallel {
!CHECK: omp.single {
!$omp parallel workshare
arr = 0
!$omp end parallel workshare
!CHECK: }
!CHECK: }
end subroutine
8 changes: 5 additions & 3 deletions libc/cmake/modules/LLVMLibCTestRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -595,9 +595,11 @@ function(add_libc_hermetic_test test_name)
get_object_files_for_test(
link_object_files skipped_entrypoints_list ${fq_deps_list})
if(skipped_entrypoints_list)
set(msg "Skipping hermetic test ${fq_target_name} as it has missing deps: "
"${skipped_entrypoints_list}.")
message(STATUS ${msg})
if(LIBC_CMAKE_VERBOSE_LOGGING)
set(msg "Skipping hermetic test ${fq_target_name} as it has missing deps: "
"${skipped_entrypoints_list}.")
message(STATUS ${msg})
endif()
return()
endif()
list(REMOVE_DUPLICATES link_object_files)
Expand Down
1 change: 1 addition & 0 deletions libc/config/baremetal/api.td
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include "config/public_api.td"

include "spec/stdc.td"
include "spec/stdc_ext.td"

def AssertMacro : MacroDef<"assert"> {
let Defn = [{
Expand Down
31 changes: 30 additions & 1 deletion libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.vsprintf
libc.src.stdio.vsnprintf


# stdbit.h entrypoints
libc.src.stdbit.stdc_leading_zeros_uc
libc.src.stdbit.stdc_leading_zeros_us
Expand Down Expand Up @@ -280,6 +279,36 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.truncl
)

if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
libc.src.stdfix.abshk
libc.src.stdfix.abshr
libc.src.stdfix.absk
libc.src.stdfix.absr
libc.src.stdfix.abslk
libc.src.stdfix.abslr
libc.src.stdfix.roundhk
libc.src.stdfix.roundhr
libc.src.stdfix.roundk
libc.src.stdfix.roundr
libc.src.stdfix.roundlk
libc.src.stdfix.roundlr
libc.src.stdfix.rounduhk
libc.src.stdfix.rounduhr
libc.src.stdfix.rounduk
libc.src.stdfix.roundur
libc.src.stdfix.roundulk
libc.src.stdfix.roundulr
libc.src.stdfix.sqrtuhk
libc.src.stdfix.sqrtuhr
libc.src.stdfix.sqrtuk
libc.src.stdfix.sqrtur
# libc.src.stdfix.sqrtulk
libc.src.stdfix.sqrtulr
)
endif()

set(TARGET_LLVMLIBC_ENTRYPOINTS
${TARGET_LIBC_ENTRYPOINTS}
${TARGET_LIBM_ENTRYPOINTS}
Expand Down
2 changes: 2 additions & 0 deletions libc/config/baremetal/arm/headers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ set(TARGET_PUBLIC_HEADERS
libc.include.fenv
libc.include.errno
libc.include.float
libc.include.stdint
libc.include.inttypes
libc.include.math
libc.include.stdfix
libc.include.stdio
libc.include.stdlib
libc.include.string
Expand Down
30 changes: 30 additions & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,36 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.truncl
)

if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
libc.src.stdfix.abshk
libc.src.stdfix.abshr
libc.src.stdfix.absk
libc.src.stdfix.absr
libc.src.stdfix.abslk
libc.src.stdfix.abslr
libc.src.stdfix.roundhk
libc.src.stdfix.roundhr
libc.src.stdfix.roundk
libc.src.stdfix.roundr
libc.src.stdfix.roundlk
libc.src.stdfix.roundlr
libc.src.stdfix.rounduhk
libc.src.stdfix.rounduhr
libc.src.stdfix.rounduk
libc.src.stdfix.roundur
libc.src.stdfix.roundulk
libc.src.stdfix.roundulr
libc.src.stdfix.sqrtuhk
libc.src.stdfix.sqrtuhr
libc.src.stdfix.sqrtuk
libc.src.stdfix.sqrtur
# libc.src.stdfix.sqrtulk
libc.src.stdfix.sqrtulr
)
endif()

set(TARGET_LLVMLIBC_ENTRYPOINTS
${TARGET_LIBC_ENTRYPOINTS}
${TARGET_LIBM_ENTRYPOINTS}
Expand Down
2 changes: 2 additions & 0 deletions libc/config/baremetal/riscv/headers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ set(TARGET_PUBLIC_HEADERS
libc.include.fenv
libc.include.errno
libc.include.float
libc.include.stdint
libc.include.inttypes
libc.include.math
libc.include.stdfix
libc.include.stdio
libc.include.stdlib
libc.include.string
Expand Down
Loading