Page MenuHomePhabricator

[clang][OpenMP] Fix runtime crash in the call to __kmp_alloc.
Needs ReviewPublic

Authored by jyu2 on Jul 15 2022, 9:08 AM.

Details

Summary

The problem is that "alloctor" from omp_init_allocator gets truncated before passing to __kmp_alloc.

To fix this, convert int type to UnsignedPointerDiffType to avoid truncate

Diff Detail

Event Timeline

jyu2 created this revision.Jul 15 2022, 9:08 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 15 2022, 9:08 AM
jyu2 requested review of this revision.Jul 15 2022, 9:08 AM

Why does it get truncated if the type must be integer? Probably, something incorrect in sema.

jyu2 added a comment.Jul 22 2022, 10:29 AM

Why does it get truncated if the type must be integer? Probably, something incorrect in sema.

This is only failed with C. But not for C++. So I don't think we have problem for Seam. I may missing something...
The different is in reprehensive of enum type between c vs c++:
For C:

-EnumDecl 0x1193f838 <line:18:9, line:33:1> line:18:14 omp_allocator_handle_t
-EnumConstantDecl 0x1193f940 <line:19:3, col:24> col:3 referenced omp_null_allocator 'int'
`-ConstantExpr 0x1193f920 <col:24> 'int'
-value: Int 0
`-IntegerLiteral 0x1193f900 <col:24> 'int' 0
-EnumConstantDecl 0x1193f9d0 <line:20:7, col:31> col:7 referenced omp_default_mem_alloc 'int'
`-ConstantExpr 0x1193f9b0 <col:31> 'int'
-value: Int 1
`-IntegerLiteral 0x1193f990 <col:31> 'int' 1

for C++:

-EnumDecl 0x11b31d88 <line:18:9, line:33:1> line:18:14 omp_allocator_handle_t
-EnumConstantDecl 0x11b31e90 <line:19:3, col:24> col:3 referenced omp_null_allocator 'omp_allocator_handle_t'
`-ImplicitCastExpr 0x11b4b770 <col:24> 'unsigned long' <IntegralCast>
`-ConstantExpr 0x11b31e70 <col:24> 'int'
-value: Int 0
`-IntegerLiteral 0x11b31e50 <col:24> 'int' 0
-EnumConstantDecl 0x11b31f20 <line:20:7, col:31> col:7 referenced omp_default_mem_alloc 'omp_allocator_handle_t'
`-ImplicitCastExpr 0x11b4b788 <col:31> 'unsigned long' <IntegralCast>
`-ConstantExpr 0x11b31f00 <col:31> 'int'
-value: Int 1
`-IntegerLiteral 0x11b31ee0 <col:31> 'int' 1

Why does it get truncated if the type must be integer? Probably, something incorrect in sema.

This is only failed with C. But not for C++. So I don't think we have problem for Seam. I may missing something...
The different is in reprehensive of enum type between c vs c++:
For C:

-EnumDecl 0x1193f838 <line:18:9, line:33:1> line:18:14 omp_allocator_handle_t
-EnumConstantDecl 0x1193f940 <line:19:3, col:24> col:3 referenced omp_null_allocator 'int'
`-ConstantExpr 0x1193f920 <col:24> 'int'
-value: Int 0
`-IntegerLiteral 0x1193f900 <col:24> 'int' 0
-EnumConstantDecl 0x1193f9d0 <line:20:7, col:31> col:7 referenced omp_default_mem_alloc 'int'
`-ConstantExpr 0x1193f9b0 <col:31> 'int'
-value: Int 1
`-IntegerLiteral 0x1193f990 <col:31> 'int' 1

for C++:

-EnumDecl 0x11b31d88 <line:18:9, line:33:1> line:18:14 omp_allocator_handle_t
-EnumConstantDecl 0x11b31e90 <line:19:3, col:24> col:3 referenced omp_null_allocator 'omp_allocator_handle_t'
`-ImplicitCastExpr 0x11b4b770 <col:24> 'unsigned long' <IntegralCast>
`-ConstantExpr 0x11b31e70 <col:24> 'int'
-value: Int 0
`-IntegerLiteral 0x11b31e50 <col:24> 'int' 0
-EnumConstantDecl 0x11b31f20 <line:20:7, col:31> col:7 referenced omp_default_mem_alloc 'omp_allocator_handle_t'
`-ImplicitCastExpr 0x11b4b788 <col:31> 'unsigned long' <IntegralCast>
`-ConstantExpr 0x11b31f00 <col:31> 'int'
-value: Int 1
`-IntegerLiteral 0x11b31ee0 <col:31> 'int' 1

If the type does not match, we have a problem with casting. Need to add an explicit cast to int-like type rather than avoid implicit casts.

jyu2 updated this revision to Diff 447372.Jul 25 2022, 9:44 AM
jyu2 edited the summary of this revision. (Show Details)
ABataev added inline comments.Jul 25 2022, 9:52 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

It must be int type, no?

jyu2 added inline comments.Jul 25 2022, 10:16 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

unsigned int?

ABataev added inline comments.Jul 25 2022, 10:20 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

Check the standard, IIRC it says just int.

jyu2 added inline comments.Jul 25 2022, 10:45 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

I see that is enum type.

Runtime library definitions: The enum types for omp_allocator_handle_t:

The type omp_allocator_handle_t, which must be an implementation-defined (for C++
possibly scoped) enum type with at least the omp_null_allocator enumerator with the
value zero and an enumerator for each predefined memory allocator in Table 2.10;

ABataev added inline comments.Jul 25 2022, 10:48 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

IIRC, in C enums are always int-based.

jyu2 added inline comments.Jul 25 2022, 11:02 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

That is right. But not for C++.

ABataev added inline comments.Jul 25 2022, 11:07 AM
clang/lib/Sema/SemaOpenMP.cpp
16379

For C++ need to get the base int type.

jyu2 added inline comments.Jul 25 2022, 12:23 PM
clang/lib/Sema/SemaOpenMP.cpp
16379

For C++ enum type is unsigned int:
since following is defined inside the omp_allocator_handle_t.
KMP_ALLOCATOR_MAX_HANDLE = (18446744073709551615UL)

But for C it is int.

-EnumDecl 0x11b31d88 <line:18:9, line:33:1> line:18:14 omp_allocator_handle_t
| |-EnumConstantDecl 0x11b31e90 <line:19:3, col:24> col:3 referenced omp_null_allocator 'omp_allocator_handle_t'
| | `-ImplicitCastExpr 0x11b4b770 <col:24> 'unsigned long' <IntegralCast>
| |   `-ConstantExpr 0x11b31e70 <col:24> 'int'
| |     |-value: Int 0
ABataev added inline comments.Jul 25 2022, 8:30 PM
clang/lib/Sema/SemaOpenMP.cpp
16379

I wouldn't rely on this, this is just implementation specific. Instead, need to find corresponding EnumDwcl and extract underlying integer type (getIntegerType). If it is null - the underlying type is int, otherwise use returned type.