Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -19568,9 +19568,6 @@ return; } - // TODO: If the result value doesn't fit in an int, it must be a long or long - // long value. ISO C does not support this, but GCC does as an extension, - // emit a warning. unsigned IntWidth = Context.getTargetInfo().getIntWidth(); unsigned CharWidth = Context.getTargetInfo().getCharWidth(); unsigned ShortWidth = Context.getTargetInfo().getShortWidth(); @@ -19690,14 +19687,24 @@ BestPromotionType = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) ? Context.UnsignedLongTy : Context.LongTy; - } else { + } else if (NumPositiveBits <= Context.getTargetInfo().getLongLongWidth()) { BestWidth = Context.getTargetInfo().getLongLongWidth(); - assert(NumPositiveBits <= BestWidth && - "How could an initializer get larger than ULL?"); BestType = Context.UnsignedLongLongTy; BestPromotionType = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) ? Context.UnsignedLongLongTy : Context.LongLongTy; + } else { + BestWidth = 128; + assert(NumPositiveBits <= BestWidth && + "How could an initializer get larger than 128-bit?"); + assert(Context.getTargetInfo().hasInt128Type() && + "How could an initializer get larger than ULL in target without " + "128-bit interger type support?"); + BestType = Context.UnsignedInt128Ty; + BestPromotionType = + (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) + ? Context.UnsignedInt128Ty + : Context.Int128Ty; } } Index: clang/test/CodeGen/enum3.c =================================================================== --- /dev/null +++ clang/test/CodeGen/enum3.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -debug-info-kind=limited -emit-llvm -o - | FileCheck %s + +enum b { + b0 = (__uint128_t)0x123456789abcdef0ULL << 64|0x0fedcba987654321ULL, +}; +__uint128_t v; + +void foo (void) +{ + v = b0; +} +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, +// CHECK-SAME: baseType: ![[BTYPE:[0-9]+]] +// CHECK-SAME: elements: ![[ELTS:[0-9]+]] +// CHECK: ![[BTYPE]] = !DIBasicType(name: "unsigned __int128", size: 128, encoding: DW_ATE_unsigned) +// CHECK: ![[ELTS]] = !{![[E:[0-9]+]]} +// CHECK: ![[E]] = !DIEnumerator(name: "b0", value: 24197857203266734864629346612071973665, isUnsigned: true) Index: clang/test/Sema/enum.c =================================================================== --- clang/test/Sema/enum.c +++ clang/test/Sema/enum.c @@ -1,4 +1,9 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple %s -fsyntax-only -verify -pedantic +enum b { + b0 = (__uint128_t)-1, // expected-warning {{ISO C restricts enumerator values to range of 'int'}} + b1 = (__uint128_t)0x123456789abcdef0ULL << 64|0x0fedcba987654321ULL, // expected-warning {{ISO C restricts enumerator values to range of 'int'}} +}; + enum e {A, B = 42LL << 32, // expected-warning {{ISO C restricts enumerator values to range of 'int'}} C = -4, D = 12456 };