Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -13227,6 +13227,7 @@ DeclContext *DC = CurContext; bool isStdBadAlloc = false; bool isStdAlignValT = false; + bool isStdByte = false; RedeclarationKind Redecl = ForRedeclaration; if (TUK == TUK_Friend || TUK == TUK_Reference) @@ -13444,6 +13445,8 @@ isStdAlignValT = true; if (Previous.empty() && StdAlignValT) Previous.addDecl(getStdAlignValT()); + } else if (Name->isStr("byte")) { + isStdByte = true; } } @@ -13845,6 +13848,13 @@ if (isStdAlignValT && (!StdAlignValT || getStdAlignValT()->isImplicit())) StdAlignValT = cast(New); + // C++1z [intro.object]p3: If a complete object is created (5.3.4) in + // storage associated with another object e of type "array of N unsigned + // char" or "array of N std::byte", that array provides storage for the + // created object [...]. + if (isStdByte) + New->addAttr(MayAliasAttr::CreateImplicit(Context, New->getLocation())); + // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; Index: test/CodeGenCXX/std-byte.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/std-byte.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++1z -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s + +// std::byte should be considered equivalent to char for aliasing. + +namespace std { +enum byte : unsigned char {}; +} + +void test0(std::byte *sb, int *i) { + // CHECK: store i8 0, i8* %{{.*}}, !tbaa [[TAG_STD_BYTE:!.*]] + // PATH: store i8 0, i8* %{{.*}}, !tbaa [[TAG_STD_BYTE:!.*]] + *sb = std::byte{0}; + + // CHECK: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] + // PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] + *i = 1; +} + +// CHECK: !"any pointer", [[TYPE_CHAR:!.*]], +// CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", [[TAG_CXX_TBAA:!.*]], +// CHECK: [[TAG_CXX_TBAA]] = !{!"Simple C++ TBAA"} +// CHECK: [[TAG_STD_BYTE]] = !{[[TYPE_STD_BYTE:!.*]], [[TYPE_STD_BYTE]], i64 0} +// CHECK: [[TYPE_STD_BYTE]] = !{!"_ZTSSt4byte", [[TYPE_CHAR]], i64 0} +// CHECK: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} +// CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]