4 changes: 3 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"
#include "clang/Sema/SemaConcept.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -3427,7 +3428,8 @@ class Sema final : public SemaBase {
bool ConstexprSupported, bool CLinkageMayDiffer);

/// type checking declaration initializers (C99 6.7.8)
bool CheckForConstantInitializer(Expr *e, QualType t);
bool CheckForConstantInitializer(
Expr *Init, unsigned DiagID = diag::err_init_element_not_constant);

QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
QualType Type, TypeSourceInfo *TSI,
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Serialization/ModuleFileExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
#define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H

#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/ExtensibleRTTI.h"
#include "llvm/Support/HashBuilder.h"
#include "llvm/Support/MD5.h"
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/PCHContainerOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "clang/Basic/Module.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryBufferRef.h"
#include <memory>

namespace llvm {
Expand Down
29 changes: 29 additions & 0 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,35 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
return true;
}

case CK_VectorSplat: {
assert(!classify(CE->getType()));
assert(classify(SubExpr->getType()));
assert(CE->getType()->isVectorType());

if (DiscardResult)
return this->discard(SubExpr);

assert(Initializing); // FIXME: Not always correct.
const auto *VT = CE->getType()->getAs<VectorType>();
PrimType ElemT = classifyPrim(SubExpr);
unsigned ElemOffset = allocateLocalPrimitive(
SubExpr, ElemT, /*IsConst=*/true, /*IsExtended=*/false);

if (!this->visit(SubExpr))
return false;
if (!this->emitSetLocal(ElemT, ElemOffset, CE))
return false;

for (unsigned I = 0; I != VT->getNumElements(); ++I) {
if (!this->emitGetLocal(ElemT, ElemOffset, CE))
return false;
if (!this->emitInitElem(ElemT, I, CE))
return false;
}

return true;
}

case CK_ToVoid:
return discard(SubExpr);

Expand Down
9 changes: 8 additions & 1 deletion clang/lib/AST/Interp/ByteCodeExprGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,20 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
return Ctx.classify(Ty);
}

/// Classifies a known primitive type
/// Classifies a known primitive type.
PrimType classifyPrim(QualType Ty) const {
if (auto T = classify(Ty)) {
return *T;
}
llvm_unreachable("not a primitive type");
}
/// Classifies a known primitive expression.
PrimType classifyPrim(const Expr *E) const {
if (auto T = classify(E))
return *T;
llvm_unreachable("not a primitive type");
}

/// Evaluates an expression and places the result on the stack. If the
/// expression is of composite type, a local variable will be created
/// and a pointer to said variable will be placed on the stack.
Expand Down
249 changes: 249 additions & 0 deletions clang/lib/Analysis/FlowSensitive/ASTOps.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
//===-- ASTOps.cc -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Operations on AST nodes that are used in flow-sensitive analysis.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include <cassert>
#include <iterator>
#include <vector>

#define DEBUG_TYPE "dataflow"

namespace clang::dataflow {

const Expr &ignoreCFGOmittedNodes(const Expr &E) {
const Expr *Current = &E;
if (auto *EWC = dyn_cast<ExprWithCleanups>(Current)) {
Current = EWC->getSubExpr();
assert(Current != nullptr);
}
Current = Current->IgnoreParens();
assert(Current != nullptr);
return *Current;
}

const Stmt &ignoreCFGOmittedNodes(const Stmt &S) {
if (auto *E = dyn_cast<Expr>(&S))
return ignoreCFGOmittedNodes(*E);
return S;
}

// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
// field decl will be modeled for all instances of the inherited field.
static void getFieldsFromClassHierarchy(QualType Type, FieldSet &Fields) {
if (Type->isIncompleteType() || Type->isDependentType() ||
!Type->isRecordType())
return;

for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
Fields.insert(Field);
if (auto *CXXRecord = Type->getAsCXXRecordDecl())
for (const CXXBaseSpecifier &Base : CXXRecord->bases())
getFieldsFromClassHierarchy(Base.getType(), Fields);
}

/// Gets the set of all fields in the type.
FieldSet getObjectFields(QualType Type) {
FieldSet Fields;
getFieldsFromClassHierarchy(Type, Fields);
return Fields;
}

bool containsSameFields(const FieldSet &Fields,
const RecordStorageLocation::FieldToLoc &FieldLocs) {
if (Fields.size() != FieldLocs.size())
return false;
for ([[maybe_unused]] auto [Field, Loc] : FieldLocs)
if (!Fields.contains(cast_or_null<FieldDecl>(Field)))
return false;
return true;
}

/// Returns the fields of a `RecordDecl` that are initialized by an
/// `InitListExpr`, in the order in which they appear in
/// `InitListExpr::inits()`.
/// `Init->getType()` must be a record type.
static std::vector<const FieldDecl *>
getFieldsForInitListExpr(const InitListExpr *InitList) {
const RecordDecl *RD = InitList->getType()->getAsRecordDecl();
assert(RD != nullptr);

std::vector<const FieldDecl *> Fields;

if (InitList->getType()->isUnionType()) {
Fields.push_back(InitList->getInitializedFieldInUnion());
return Fields;
}

// Unnamed bitfields are only used for padding and do not appear in
// `InitListExpr`'s inits. However, those fields do appear in `RecordDecl`'s
// field list, and we thus need to remove them before mapping inits to
// fields to avoid mapping inits to the wrongs fields.
llvm::copy_if(
RD->fields(), std::back_inserter(Fields),
[](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });
return Fields;
}

RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) {
auto *RD = InitList->getType()->getAsCXXRecordDecl();
assert(RD != nullptr);

std::vector<const FieldDecl *> Fields = getFieldsForInitListExpr(InitList);
ArrayRef<Expr *> Inits = InitList->inits();

// Unions initialized with an empty initializer list need special treatment.
// For structs/classes initialized with an empty initializer list, Clang
// puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions,
// it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
SmallVector<Expr *> InitsForUnion;
if (InitList->getType()->isUnionType() && Inits.empty()) {
assert(Fields.size() == 1);
ImplicitValueInitForUnion.emplace(Fields.front()->getType());
InitsForUnion.push_back(&*ImplicitValueInitForUnion);
Inits = InitsForUnion;
}

size_t InitIdx = 0;

assert(Fields.size() + RD->getNumBases() == Inits.size());
for (const CXXBaseSpecifier &Base : RD->bases()) {
assert(InitIdx < Inits.size());
Expr *Init = Inits[InitIdx++];
BaseInits.emplace_back(&Base, Init);
}

assert(Fields.size() == Inits.size() - InitIdx);
for (const FieldDecl *Field : Fields) {
assert(InitIdx < Inits.size());
Expr *Init = Inits[InitIdx++];
FieldInits.emplace_back(Field, Init);
}
}

static void insertIfGlobal(const Decl &D,
llvm::DenseSet<const VarDecl *> &Globals) {
if (auto *V = dyn_cast<VarDecl>(&D))
if (V->hasGlobalStorage())
Globals.insert(V);
}

static void insertIfFunction(const Decl &D,
llvm::DenseSet<const FunctionDecl *> &Funcs) {
if (auto *FD = dyn_cast<FunctionDecl>(&D))
Funcs.insert(FD);
}

static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
// Use getCalleeDecl instead of getMethodDecl in order to handle
// pointer-to-member calls.
const auto *MethodDecl = dyn_cast_or_null<CXXMethodDecl>(C.getCalleeDecl());
if (!MethodDecl)
return nullptr;
auto *Body = dyn_cast_or_null<CompoundStmt>(MethodDecl->getBody());
if (!Body || Body->size() != 1)
return nullptr;
if (auto *RS = dyn_cast<ReturnStmt>(*Body->body_begin()))
if (auto *Return = RS->getRetValue())
return dyn_cast<MemberExpr>(Return->IgnoreParenImpCasts());
return nullptr;
}

static void getReferencedDecls(const Decl &D, ReferencedDecls &Referenced) {
insertIfGlobal(D, Referenced.Globals);
insertIfFunction(D, Referenced.Functions);
if (const auto *Decomp = dyn_cast<DecompositionDecl>(&D))
for (const auto *B : Decomp->bindings())
if (auto *ME = dyn_cast_or_null<MemberExpr>(B->getBinding()))
// FIXME: should we be using `E->getFoundDecl()`?
if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
Referenced.Fields.insert(FD);
}

/// Traverses `S` and inserts into `Referenced` any declarations that are
/// declared in or referenced from sub-statements.
static void getReferencedDecls(const Stmt &S, ReferencedDecls &Referenced) {
for (auto *Child : S.children())
if (Child != nullptr)
getReferencedDecls(*Child, Referenced);
if (const auto *DefaultArg = dyn_cast<CXXDefaultArgExpr>(&S))
getReferencedDecls(*DefaultArg->getExpr(), Referenced);
if (const auto *DefaultInit = dyn_cast<CXXDefaultInitExpr>(&S))
getReferencedDecls(*DefaultInit->getExpr(), Referenced);

if (auto *DS = dyn_cast<DeclStmt>(&S)) {
if (DS->isSingleDecl())
getReferencedDecls(*DS->getSingleDecl(), Referenced);
else
for (auto *D : DS->getDeclGroup())
getReferencedDecls(*D, Referenced);
} else if (auto *E = dyn_cast<DeclRefExpr>(&S)) {
insertIfGlobal(*E->getDecl(), Referenced.Globals);
insertIfFunction(*E->getDecl(), Referenced.Functions);
} else if (const auto *C = dyn_cast<CXXMemberCallExpr>(&S)) {
// If this is a method that returns a member variable but does nothing else,
// model the field of the return value.
if (MemberExpr *E = getMemberForAccessor(*C))
if (const auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()))
Referenced.Fields.insert(FD);
} else if (auto *E = dyn_cast<MemberExpr>(&S)) {
// FIXME: should we be using `E->getFoundDecl()`?
const ValueDecl *VD = E->getMemberDecl();
insertIfGlobal(*VD, Referenced.Globals);
insertIfFunction(*VD, Referenced.Functions);
if (const auto *FD = dyn_cast<FieldDecl>(VD))
Referenced.Fields.insert(FD);
} else if (auto *InitList = dyn_cast<InitListExpr>(&S)) {
if (InitList->getType()->isRecordType())
for (const auto *FD : getFieldsForInitListExpr(InitList))
Referenced.Fields.insert(FD);
}
}

ReferencedDecls getReferencedDecls(const FunctionDecl &FD) {
ReferencedDecls Result;
// Look for global variable and field references in the
// constructor-initializers.
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(&FD)) {
for (const auto *Init : CtorDecl->inits()) {
if (Init->isMemberInitializer()) {
Result.Fields.insert(Init->getMember());
} else if (Init->isIndirectMemberInitializer()) {
for (const auto *I : Init->getIndirectMember()->chain())
Result.Fields.insert(cast<FieldDecl>(I));
}
const Expr *E = Init->getInit();
assert(E != nullptr);
getReferencedDecls(*E, Result);
}
// Add all fields mentioned in default member initializers.
for (const FieldDecl *F : CtorDecl->getParent()->fields())
if (const auto *I = F->getInClassInitializer())
getReferencedDecls(*I, Result);
}
getReferencedDecls(*FD.getBody(), Result);

return Result;
}

} // namespace clang::dataflow
1 change: 1 addition & 0 deletions clang/lib/Analysis/FlowSensitive/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_clang_library(clangAnalysisFlowSensitive
AdornedCFG.cpp
Arena.cpp
ASTOps.cpp
DataflowAnalysisContext.cpp
DataflowEnvironment.cpp
Formula.cpp
Expand Down
53 changes: 1 addition & 52 deletions clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "clang/Analysis/FlowSensitive/DebugSupport.h"
#include "clang/Analysis/FlowSensitive/Formula.h"
#include "clang/Analysis/FlowSensitive/Logger.h"
Expand Down Expand Up @@ -359,55 +360,3 @@ DataflowAnalysisContext::~DataflowAnalysisContext() = default;

} // namespace dataflow
} // namespace clang

using namespace clang;

const Expr &clang::dataflow::ignoreCFGOmittedNodes(const Expr &E) {
const Expr *Current = &E;
if (auto *EWC = dyn_cast<ExprWithCleanups>(Current)) {
Current = EWC->getSubExpr();
assert(Current != nullptr);
}
Current = Current->IgnoreParens();
assert(Current != nullptr);
return *Current;
}

const Stmt &clang::dataflow::ignoreCFGOmittedNodes(const Stmt &S) {
if (auto *E = dyn_cast<Expr>(&S))
return ignoreCFGOmittedNodes(*E);
return S;
}

// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
// field decl will be modeled for all instances of the inherited field.
static void getFieldsFromClassHierarchy(QualType Type,
clang::dataflow::FieldSet &Fields) {
if (Type->isIncompleteType() || Type->isDependentType() ||
!Type->isRecordType())
return;

for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
Fields.insert(Field);
if (auto *CXXRecord = Type->getAsCXXRecordDecl())
for (const CXXBaseSpecifier &Base : CXXRecord->bases())
getFieldsFromClassHierarchy(Base.getType(), Fields);
}

/// Gets the set of all fields in the type.
clang::dataflow::FieldSet clang::dataflow::getObjectFields(QualType Type) {
FieldSet Fields;
getFieldsFromClassHierarchy(Type, Fields);
return Fields;
}

bool clang::dataflow::containsSameFields(
const clang::dataflow::FieldSet &Fields,
const clang::dataflow::RecordStorageLocation::FieldToLoc &FieldLocs) {
if (Fields.size() != FieldLocs.size())
return false;
for ([[maybe_unused]] auto [Field, Loc] : FieldLocs)
if (!Fields.contains(cast_or_null<FieldDecl>(Field)))
return false;
return true;
}
177 changes: 5 additions & 172 deletions clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
Expand Down Expand Up @@ -304,93 +305,6 @@ widenKeyToValueMap(const llvm::MapVector<Key, Value *> &CurMap,
return WidenedMap;
}

/// Initializes a global storage value.
static void insertIfGlobal(const Decl &D,
llvm::DenseSet<const VarDecl *> &Vars) {
if (auto *V = dyn_cast<VarDecl>(&D))
if (V->hasGlobalStorage())
Vars.insert(V);
}

static void insertIfFunction(const Decl &D,
llvm::DenseSet<const FunctionDecl *> &Funcs) {
if (auto *FD = dyn_cast<FunctionDecl>(&D))
Funcs.insert(FD);
}

static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
// Use getCalleeDecl instead of getMethodDecl in order to handle
// pointer-to-member calls.
const auto *MethodDecl = dyn_cast_or_null<CXXMethodDecl>(C.getCalleeDecl());
if (!MethodDecl)
return nullptr;
auto *Body = dyn_cast_or_null<CompoundStmt>(MethodDecl->getBody());
if (!Body || Body->size() != 1)
return nullptr;
if (auto *RS = dyn_cast<ReturnStmt>(*Body->body_begin()))
if (auto *Return = RS->getRetValue())
return dyn_cast<MemberExpr>(Return->IgnoreParenImpCasts());
return nullptr;
}

static void
getFieldsGlobalsAndFuncs(const Decl &D, FieldSet &Fields,
llvm::DenseSet<const VarDecl *> &Vars,
llvm::DenseSet<const FunctionDecl *> &Funcs) {
insertIfGlobal(D, Vars);
insertIfFunction(D, Funcs);
if (const auto *Decomp = dyn_cast<DecompositionDecl>(&D))
for (const auto *B : Decomp->bindings())
if (auto *ME = dyn_cast_or_null<MemberExpr>(B->getBinding()))
// FIXME: should we be using `E->getFoundDecl()`?
if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
Fields.insert(FD);
}

/// Traverses `S` and inserts into `Fields`, `Vars` and `Funcs` any fields,
/// global variables and functions that are declared in or referenced from
/// sub-statements.
static void
getFieldsGlobalsAndFuncs(const Stmt &S, FieldSet &Fields,
llvm::DenseSet<const VarDecl *> &Vars,
llvm::DenseSet<const FunctionDecl *> &Funcs) {
for (auto *Child : S.children())
if (Child != nullptr)
getFieldsGlobalsAndFuncs(*Child, Fields, Vars, Funcs);
if (const auto *DefaultArg = dyn_cast<CXXDefaultArgExpr>(&S))
getFieldsGlobalsAndFuncs(*DefaultArg->getExpr(), Fields, Vars, Funcs);
if (const auto *DefaultInit = dyn_cast<CXXDefaultInitExpr>(&S))
getFieldsGlobalsAndFuncs(*DefaultInit->getExpr(), Fields, Vars, Funcs);

if (auto *DS = dyn_cast<DeclStmt>(&S)) {
if (DS->isSingleDecl())
getFieldsGlobalsAndFuncs(*DS->getSingleDecl(), Fields, Vars, Funcs);
else
for (auto *D : DS->getDeclGroup())
getFieldsGlobalsAndFuncs(*D, Fields, Vars, Funcs);
} else if (auto *E = dyn_cast<DeclRefExpr>(&S)) {
insertIfGlobal(*E->getDecl(), Vars);
insertIfFunction(*E->getDecl(), Funcs);
} else if (const auto *C = dyn_cast<CXXMemberCallExpr>(&S)) {
// If this is a method that returns a member variable but does nothing else,
// model the field of the return value.
if (MemberExpr *E = getMemberForAccessor(*C))
if (const auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()))
Fields.insert(FD);
} else if (auto *E = dyn_cast<MemberExpr>(&S)) {
// FIXME: should we be using `E->getFoundDecl()`?
const ValueDecl *VD = E->getMemberDecl();
insertIfGlobal(*VD, Vars);
insertIfFunction(*VD, Funcs);
if (const auto *FD = dyn_cast<FieldDecl>(VD))
Fields.insert(FD);
} else if (auto *InitList = dyn_cast<InitListExpr>(&S)) {
if (InitList->getType()->isRecordType())
for (const auto *FD : getFieldsForInitListExpr(InitList))
Fields.insert(FD);
}
}

namespace {

// Visitor that builds a map from record prvalues to result objects.
Expand Down Expand Up @@ -653,36 +567,13 @@ void Environment::initialize() {
void Environment::initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl) {
assert(FuncDecl->doesThisDeclarationHaveABody());

FieldSet Fields;
llvm::DenseSet<const VarDecl *> Vars;
llvm::DenseSet<const FunctionDecl *> Funcs;

// Look for global variable and field references in the
// constructor-initializers.
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FuncDecl)) {
for (const auto *Init : CtorDecl->inits()) {
if (Init->isMemberInitializer()) {
Fields.insert(Init->getMember());
} else if (Init->isIndirectMemberInitializer()) {
for (const auto *I : Init->getIndirectMember()->chain())
Fields.insert(cast<FieldDecl>(I));
}
const Expr *E = Init->getInit();
assert(E != nullptr);
getFieldsGlobalsAndFuncs(*E, Fields, Vars, Funcs);
}
// Add all fields mentioned in default member initializers.
for (const FieldDecl *F : CtorDecl->getParent()->fields())
if (const auto *I = F->getInClassInitializer())
getFieldsGlobalsAndFuncs(*I, Fields, Vars, Funcs);
}
getFieldsGlobalsAndFuncs(*FuncDecl->getBody(), Fields, Vars, Funcs);
ReferencedDecls Referenced = getReferencedDecls(*FuncDecl);

// These have to be added before the lines that follow to ensure that
// `create*` work correctly for structs.
DACtx->addModeledFields(Fields);
DACtx->addModeledFields(Referenced.Fields);

for (const VarDecl *D : Vars) {
for (const VarDecl *D : Referenced.Globals) {
if (getStorageLocation(*D) != nullptr)
continue;

Expand All @@ -694,7 +585,7 @@ void Environment::initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl) {
setStorageLocation(*D, createObject(*D, nullptr));
}

for (const FunctionDecl *FD : Funcs) {
for (const FunctionDecl *FD : Referenced.Functions) {
if (getStorageLocation(*FD) != nullptr)
continue;
auto &Loc = createStorageLocation(*FD);
Expand Down Expand Up @@ -1354,64 +1245,6 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
return Env.get<RecordStorageLocation>(*Base);
}

std::vector<const FieldDecl *>
getFieldsForInitListExpr(const InitListExpr *InitList) {
const RecordDecl *RD = InitList->getType()->getAsRecordDecl();
assert(RD != nullptr);

std::vector<const FieldDecl *> Fields;

if (InitList->getType()->isUnionType()) {
Fields.push_back(InitList->getInitializedFieldInUnion());
return Fields;
}

// Unnamed bitfields are only used for padding and do not appear in
// `InitListExpr`'s inits. However, those fields do appear in `RecordDecl`'s
// field list, and we thus need to remove them before mapping inits to
// fields to avoid mapping inits to the wrongs fields.
llvm::copy_if(
RD->fields(), std::back_inserter(Fields),
[](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });
return Fields;
}

RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) {
auto *RD = InitList->getType()->getAsCXXRecordDecl();
assert(RD != nullptr);

std::vector<const FieldDecl *> Fields = getFieldsForInitListExpr(InitList);
ArrayRef<Expr *> Inits = InitList->inits();

// Unions initialized with an empty initializer list need special treatment.
// For structs/classes initialized with an empty initializer list, Clang
// puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions,
// it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
SmallVector<Expr *> InitsForUnion;
if (InitList->getType()->isUnionType() && Inits.empty()) {
assert(Fields.size() == 1);
ImplicitValueInitForUnion.emplace(Fields.front()->getType());
InitsForUnion.push_back(&*ImplicitValueInitForUnion);
Inits = InitsForUnion;
}

size_t InitIdx = 0;

assert(Fields.size() + RD->getNumBases() == Inits.size());
for (const CXXBaseSpecifier &Base : RD->bases()) {
assert(InitIdx < Inits.size());
Expr *Init = Inits[InitIdx++];
BaseInits.emplace_back(&Base, Init);
}

assert(Fields.size() == Inits.size() - InitIdx);
for (const FieldDecl *Field : Fields) {
assert(InitIdx < Inits.size());
Expr *Init = Inits[InitIdx++];
FieldInits.emplace_back(Field, Init);
}
}

RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) {
auto &NewVal = Env.create<RecordValue>(Loc);
Env.setValue(Loc, NewVal);
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Analysis/FlowSensitive/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
#include "clang/Analysis/FlowSensitive/RecordOps.h"
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
// SPIR-V IDs are represented with a single 32-bit word.
SizeType = TargetInfo::UnsignedInt;
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
}

void getTargetDefines(const LangOptions &Opts,
Expand Down
28 changes: 11 additions & 17 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12671,7 +12671,7 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) {
}
}

bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
bool Sema::CheckForConstantInitializer(Expr *Init, unsigned DiagID) {
// FIXME: Need strict checking. In C89, we need to check for
// any assignment, increment, decrement, function-calls, or
// commas outside of a sizeof. In C99, it's the same list,
Expand All @@ -12689,8 +12689,7 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
const Expr *Culprit;
if (Init->isConstantInitializer(Context, false, &Culprit))
return false;
Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
<< Culprit->getSourceRange();
Diag(Culprit->getExprLoc(), DiagID) << Culprit->getSourceRange();
return true;
}

Expand Down Expand Up @@ -13808,29 +13807,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
// This is true even in C++ for OpenCL.
} else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
CheckForConstantInitializer(Init, DclT);
CheckForConstantInitializer(Init);

// Otherwise, C++ does not restrict the initializer.
// Otherwise, C++ does not restrict the initializer.
} else if (getLangOpts().CPlusPlus) {
// do nothing

// C99 6.7.8p4: All the expressions in an initializer for an object that has
// static storage duration shall be constant expressions or string literals.
} else if (VDecl->getStorageClass() == SC_Static) {
CheckForConstantInitializer(Init, DclT);
CheckForConstantInitializer(Init);

// C89 is stricter than C99 for aggregate initializers.
// C89 6.5.7p3: All the expressions [...] in an initializer list
// for an object that has aggregate or union type shall be
// constant expressions.
// C89 is stricter than C99 for aggregate initializers.
// C89 6.5.7p3: All the expressions [...] in an initializer list
// for an object that has aggregate or union type shall be
// constant expressions.
} else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
isa<InitListExpr>(Init)) {
const Expr *Culprit;
if (!Init->isConstantInitializer(Context, false, &Culprit)) {
Diag(Culprit->getExprLoc(),
diag::ext_aggregate_init_not_constant)
<< Culprit->getSourceRange();
}
CheckForConstantInitializer(Init, diag::ext_aggregate_init_not_constant);
}

if (auto *E = dyn_cast<ExprWithCleanups>(Init))
Expand Down Expand Up @@ -13963,7 +13957,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// Avoid duplicate diagnostics for constexpr variables.
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
!VDecl->isConstexpr())
CheckForConstantInitializer(Init, DclT);
CheckForConstantInitializer(Init);
}

QualType InitType = Init->getType();
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2001,6 +2001,8 @@ static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
LookupResult LR(S, Target, Sema::LookupOrdinaryName);
if (S.LookupName(LR, S.TUScope)) {
for (NamedDecl *ND : LR) {
if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND))
continue;
if (MC->shouldMangleDeclName(ND)) {
llvm::raw_svector_ostream Out(Name);
Name.clear();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7331,7 +7331,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
if (!LiteralExpr->isTypeDependent() &&
!LiteralExpr->isValueDependent() &&
!literalType->isDependentType()) // C99 6.5.2.5p3
if (CheckForConstantInitializer(LiteralExpr, literalType))
if (CheckForConstantInitializer(LiteralExpr))
return ExprError();
} else if (literalType.getAddressSpace() != LangAS::opencl_private &&
literalType.getAddressSpace() != LangAS::Default) {
Expand Down
26 changes: 14 additions & 12 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6114,7 +6114,8 @@ InitializationSequence::InitializationSequence(
Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
MultiExprArg Args, bool TopLevelOfInitList, bool TreatUnavailableAsInvalid)
: FailedOverloadResult(OR_Success),
FailedCandidateSet(Kind.getLocation(), OverloadCandidateSet::CSK_Normal) {
FailedCandidateSet(new OverloadCandidateSet(
Kind.getLocation(), OverloadCandidateSet::CSK_Normal)) {
InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList,
TreatUnavailableAsInvalid);
}
Expand Down Expand Up @@ -9735,7 +9736,7 @@ bool InitializationSequence::Diagnose(Sema &S,
switch (FailedOverloadResult) {
case OR_Ambiguous:

FailedCandidateSet.NoteCandidates(
FailedCandidateSet->NoteCandidates(
PartialDiagnosticAt(
Kind.getLocation(),
Failure == FK_UserConversionOverloadFailed
Expand All @@ -9749,7 +9750,8 @@ bool InitializationSequence::Diagnose(Sema &S,
break;

case OR_No_Viable_Function: {
auto Cands = FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args);
auto Cands =
FailedCandidateSet->CompleteCandidates(S, OCD_AllCandidates, Args);
if (!S.RequireCompleteType(Kind.getLocation(),
DestType.getNonReferenceType(),
diag::err_typecheck_nonviable_condition_incomplete,
Expand All @@ -9759,13 +9761,13 @@ bool InitializationSequence::Diagnose(Sema &S,
<< OnlyArg->getType() << Args[0]->getSourceRange()
<< DestType.getNonReferenceType();

FailedCandidateSet.NoteCandidates(S, Args, Cands);
FailedCandidateSet->NoteCandidates(S, Args, Cands);
break;
}
case OR_Deleted: {
OverloadCandidateSet::iterator Best;
OverloadingResult Ovl
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
OverloadingResult Ovl =
FailedCandidateSet->BestViableFunction(S, Kind.getLocation(), Best);

StringLiteral *Msg = Best->Function->getDeletedMessage();
S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
Expand Down Expand Up @@ -9949,7 +9951,7 @@ bool InitializationSequence::Diagnose(Sema &S,
// bad.
switch (FailedOverloadResult) {
case OR_Ambiguous:
FailedCandidateSet.NoteCandidates(
FailedCandidateSet->NoteCandidates(
PartialDiagnosticAt(Kind.getLocation(),
S.PDiag(diag::err_ovl_ambiguous_init)
<< DestType << ArgsRange),
Expand Down Expand Up @@ -10003,7 +10005,7 @@ bool InitializationSequence::Diagnose(Sema &S,
break;
}

FailedCandidateSet.NoteCandidates(
FailedCandidateSet->NoteCandidates(
PartialDiagnosticAt(
Kind.getLocation(),
S.PDiag(diag::err_ovl_no_viable_function_in_init)
Expand All @@ -10013,8 +10015,8 @@ bool InitializationSequence::Diagnose(Sema &S,

case OR_Deleted: {
OverloadCandidateSet::iterator Best;
OverloadingResult Ovl
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
OverloadingResult Ovl =
FailedCandidateSet->BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl != OR_Deleted) {
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
<< DestType << ArgsRange;
Expand Down Expand Up @@ -10093,8 +10095,8 @@ bool InitializationSequence::Diagnose(Sema &S,
S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor)
<< Args[0]->getSourceRange();
OverloadCandidateSet::iterator Best;
OverloadingResult Ovl
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
OverloadingResult Ovl =
FailedCandidateSet->BestViableFunction(S, Kind.getLocation(), Best);
(void)Ovl;
assert(Ovl == OR_Success && "Inconsistent overload resolution");
CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
Expand Down
21 changes: 11 additions & 10 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1057,17 +1057,14 @@ bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed(

void OverloadCandidateSet::destroyCandidates() {
for (iterator i = begin(), e = end(); i != e; ++i) {
for (auto &C : i->Conversions)
C.~ImplicitConversionSequence();
delete[] i->Conversions.data();
if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction)
i->DeductionFailure.Destroy();
}
}

void OverloadCandidateSet::clear(CandidateSetKind CSK) {
destroyCandidates();
SlabAllocator.Reset();
NumInlineBytesUsed = 0;
Candidates.clear();
Functions.clear();
Kind = CSK;
Expand Down Expand Up @@ -6983,7 +6980,7 @@ void Sema::AddOverloadCandidate(
Candidate.RewriteKind =
CandidateSet.getRewriteInfo().getRewriteKind(Function, PO);
Candidate.IsSurrogate = false;
Candidate.IsADLCandidate = IsADLCandidate;
Candidate.IsADLCandidate = static_cast<unsigned>(IsADLCandidate);
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = Args.size();

Expand Down Expand Up @@ -7815,7 +7812,7 @@ void Sema::AddTemplateOverloadCandidate(
Candidate.RewriteKind =
CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO);
Candidate.IsSurrogate = false;
Candidate.IsADLCandidate = IsADLCandidate;
Candidate.IsADLCandidate = static_cast<unsigned>(IsADLCandidate);
// Ignore the object argument if there is one, since we don't have an object
// type.
Candidate.IgnoreObjectArgument =
Expand Down Expand Up @@ -14125,7 +14122,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
return ExprError();
return SemaRef.BuildResolvedCallExpr(
Res.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig,
/*IsExecConfig=*/false, (*Best)->IsADLCandidate);
/*IsExecConfig=*/false,
static_cast<CallExpr::ADLCallKind>((*Best)->IsADLCandidate));
}

case OR_No_Viable_Function: {
Expand Down Expand Up @@ -14184,7 +14182,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
return ExprError();
return SemaRef.BuildResolvedCallExpr(
Res.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig,
/*IsExecConfig=*/false, (*Best)->IsADLCandidate);
/*IsExecConfig=*/false,
static_cast<CallExpr::ADLCallKind>((*Best)->IsADLCandidate));
}
}

Expand Down Expand Up @@ -14491,7 +14490,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
Args[0] = Input;
CallExpr *TheCall = CXXOperatorCallExpr::Create(
Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc,
CurFPFeatureOverrides(), Best->IsADLCandidate);
CurFPFeatureOverrides(),
static_cast<CallExpr::ADLCallKind>(Best->IsADLCandidate));

if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
return ExprError();
Expand Down Expand Up @@ -14909,7 +14909,8 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// members; CodeGen should take care not to emit the this pointer.
TheCall = CXXOperatorCallExpr::Create(
Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc,
CurFPFeatureOverrides(), Best->IsADLCandidate);
CurFPFeatureOverrides(),
static_cast<CallExpr::ADLCallKind>(Best->IsADLCandidate));

if (const auto *Method = dyn_cast<CXXMethodDecl>(FnDecl);
Method && Method->isImplicitObjectMemberFunction()) {
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ODRDiagsEmitter.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/OpenACCClause.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/RawCommentList.h"
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/ASTWriterDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/SourceManager.h"
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Lex/Token.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
using namespace clang;
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/GeneratePCH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"

Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/GlobalModuleIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "clang/Serialization/GlobalModuleIndex.h"
#include "ASTReaderInternals.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ModuleFile.h"
#include "clang/Serialization/PCHContainerOperations.h"
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ModuleFileExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/ADT/Hashing.h"

using namespace clang;

char ModuleFileExtension::ID = 0;
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/Serialization/PCHContainerOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

#include "clang/Serialization/PCHContainerOperations.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>

Expand Down
17 changes: 15 additions & 2 deletions clang/test/AST/Interp/vectors.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -verify=ref,both %s

// ref-no-diagnostics

typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 A = {1,2,3,4};
static_assert(A[0] == 1, ""); // ref-error {{not an integral constant expression}}
static_assert(A[1] == 2, ""); // ref-error {{not an integral constant expression}}
static_assert(A[2] == 3, ""); // ref-error {{not an integral constant expression}}
static_assert(A[3] == 4, ""); // ref-error {{not an integral constant expression}}

/// VectorSplat casts
typedef __attribute__(( ext_vector_type(4) )) float float4;
constexpr float4 vec4_0 = (float4)0.5f;
static_assert(vec4_0[0] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[1] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[2] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[3] == 0.5, ""); // ref-error {{not an integral constant expression}}
constexpr int vec4_0_discarded = ((float4)12.0f, 0);



/// From constant-expression-cxx11.cpp
namespace Vector {
Expand Down
14 changes: 9 additions & 5 deletions clang/test/CXX/drs/dr0xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

namespace cwg1 { // cwg1: no
namespace X { extern "C" void cwg1_f(int a = 1); }
namespace Y { extern "C" void cwg1_f(int a = 1); }
Expand Down Expand Up @@ -897,7 +902,7 @@ namespace cwg54 { // cwg54: 2.8

namespace cwg55 { // cwg55: yes
enum E { e = 5 };
int test[(e + 1 == 6) ? 1 : -1];
static_assert(e + 1 == 6, "");
}

namespace cwg56 { // cwg56: yes
Expand Down Expand Up @@ -1163,10 +1168,9 @@ namespace cwg75 { // cwg75: yes

namespace cwg76 { // cwg76: yes
const volatile int n = 1;
int arr[n]; // #cwg76-vla
// expected-error@#cwg76-vla {{variable length arrays in C++ are a Clang extension}}
// expected-note@#cwg76-vla {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
// expected-error@#cwg76-vla {{variable length array declaration not allowed at file scope}}
static_assert(n, "");
// expected-error@-1 {{static assertion expression is not an integral constant expression}}
// expected-note@-2 {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
}

namespace cwg77 { // cwg77: yes
Expand Down
5 changes: 2 additions & 3 deletions clang/test/CXX/drs/dr16xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,9 @@ namespace cwg1645 { // cwg1645: 3.9

namespace cwg1652 { // cwg1652: 3.6
int a, b;
int arr[&a + 1 == &b ? 1 : 2];
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
static_assert(&a + 1 == &b, "");
// expected-error@-1 {{static assertion expression is not an integral constant expression}}
// expected-note@-2 {{comparison against pointer '&a + 1' that points past the end of a complete object has unspecified value}}
// expected-error@-3 {{variable length array declaration not allowed at file scope}}
}

namespace cwg1653 { // cwg1653: 4 c++17
Expand Down
61 changes: 33 additions & 28 deletions clang/test/CXX/drs/dr1xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

#if __cplusplus == 199711L
#define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x))
#else
#define __enable_constant_folding
#endif

namespace cwg100 { // cwg100: yes
template<const char (*)[4]> struct A {}; // #cwg100-A
template<const char (&)[4]> struct B {}; // #cwg100-B
Expand Down Expand Up @@ -736,22 +747,16 @@ namespace cwg147 { // cwg147: yes

namespace cwg148 { // cwg148: yes
struct A { int A::*p; };
int check1[__is_pod(int(A::*)) ? 1 : -1];
int check2[__is_pod(A) ? 1 : -1];
static_assert(__is_pod(int(A::*)), "");
static_assert(__is_pod(A), "");
}

// cwg149: na

namespace cwg151 { // cwg151: 3.1
struct X {};
typedef int X::*p;
#if __cplusplus < 201103L
#define fold(x) (__builtin_constant_p(0) ? (x) : (x))
#else
#define fold
#endif
int check[fold(p() == 0) ? 1 : -1];
#undef fold
static_assert(__enable_constant_folding(p() == 0), "");
}

namespace cwg152 { // cwg152: yes
Expand Down Expand Up @@ -956,42 +961,42 @@ namespace cwg171 {

namespace cwg172 { // cwg172: yes
enum { zero };
int check1[-1 < zero ? 1 : -1];
static_assert(-1 < zero, "");

enum { x = -1, y = (unsigned int)-1 };
int check2[sizeof(x) > sizeof(int) ? 1 : -1];
static_assert(sizeof(x) > sizeof(int), "");

enum { a = (unsigned int)-1 / 2 };
int check3a[sizeof(a) == sizeof(int) ? 1 : -1];
int check3b[-a < 0 ? 1 : -1];
static_assert(sizeof(a) == sizeof(int), "");
static_assert(-a < 0, "");

enum { b = (unsigned int)-1 / 2 + 1 };
int check4a[sizeof(b) == sizeof(unsigned int) ? 1 : -1];
int check4b[-b > 0 ? 1 : -1];
static_assert(sizeof(b) == sizeof(unsigned int), "");
static_assert(-b > 0, "");

enum { c = (unsigned long)-1 / 2 };
int check5a[sizeof(c) == sizeof(long) ? 1 : -1];
int check5b[-c < 0 ? 1 : -1];
static_assert(sizeof(c) == sizeof(long), "");
static_assert(-c < 0, "");

enum { d = (unsigned long)-1 / 2 + 1 };
int check6a[sizeof(d) == sizeof(unsigned long) ? 1 : -1];
int check6b[-d > 0 ? 1 : -1];
static_assert(sizeof(d) == sizeof(unsigned long), "");
static_assert(-d > 0, "");

enum { e = (unsigned long long)-1 / 2 };
// cxx98-error@-1 {{'long long' is a C++11 extension}}
int check7a[sizeof(e) == sizeof(long) ? 1 : -1];
int check7b[-e < 0 ? 1 : -1];
static_assert(sizeof(e) == sizeof(long), "");
static_assert(-e < 0, "");

enum { f = (unsigned long long)-1 / 2 + 1 };
// cxx98-error@-1 {{'long long' is a C++11 extension}}
int check8a[sizeof(f) == sizeof(unsigned long) ? 1 : -1];
int check8b[-f > 0 ? 1 : -1];
static_assert(sizeof(f) == sizeof(unsigned long), "");
static_assert(-f > 0, "");
}

namespace cwg173 { // cwg173: yes
int check[('0' + 1 == '1' && '0' + 2 == '2' && '0' + 3 == '3' &&
'0' + 4 == '4' && '0' + 5 == '5' && '0' + 6 == '6' &&
'0' + 7 == '7' && '0' + 8 == '8' && '0' + 9 == '9') ? 1 : -1];
static_assert('0' + 1 == '1' && '0' + 2 == '2' && '0' + 3 == '3' &&
'0' + 4 == '4' && '0' + 5 == '5' && '0' + 6 == '6' &&
'0' + 7 == '7' && '0' + 8 == '8' && '0' + 9 == '9', "");
}

// cwg174: sup 1012
Expand Down Expand Up @@ -1070,7 +1075,7 @@ namespace cwg177 { // cwg177: yes
}

namespace cwg178 { // cwg178: yes
int check[int() == 0 ? 1 : -1];
static_assert(int() == 0, "");
#if __cplusplus >= 201103L
static_assert(int{} == 0, "");
struct S { int a, b; };
Expand Down Expand Up @@ -1180,7 +1185,7 @@ namespace cwg187 { // cwg187: sup 481

namespace cwg188 { // cwg188: yes
char c[10];
int check[sizeof(0, c) == 10 ? 1 : -1];
static_assert(sizeof(0, c) == 10, "");
}

// cwg190 FIXME: add codegen test for tbaa
Expand Down
15 changes: 10 additions & 5 deletions clang/test/CXX/drs/dr2xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
typedef __SIZE_TYPE__ size_t;
// cxx98-error@-1 0-1 {{'long long' is a C++11 extension}}

#if __cplusplus < 201103L
#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

#if __cplusplus == 199711L
#define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x))
#else
#define fold
#define __enable_constant_folding
#endif

namespace cwg200 { // cwg200: dup 214
Expand All @@ -31,7 +36,7 @@ namespace cwg200 { // cwg200: dup 214
namespace cwg202 { // cwg202: 3.1
template<typename T> T f();
template<int (*g)()> struct X {
int arr[fold(g == &f<int>) ? 1 : -1];
static_assert(__enable_constant_folding(g == &f<int>), "");
};
template struct X<f>;
}
Expand Down Expand Up @@ -1024,7 +1029,7 @@ namespace cwg275 { // cwg275: no
namespace cwg277 { // cwg277: 3.1
typedef int *intp;
int *p = intp();
int a[fold(intp() ? -1 : 1)];
static_assert(__enable_constant_folding(!intp()), "");
}

namespace cwg280 { // cwg280: 2.9
Expand Down
38 changes: 21 additions & 17 deletions clang/test/CXX/drs/dr3xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
// RUN: %clang_cc1 -std=c++11 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx11-14,since-cxx11 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++98 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx98 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

#if __cplusplus == 199711L
#define __enable_constant_folding(x) (__builtin_constant_p(x) ? (x) : (x))
#else
#define __enable_constant_folding
#endif

namespace cwg300 { // cwg300: yes
template<typename R, typename A> void f(R (&)(A)) {}
int g(int);
Expand Down Expand Up @@ -396,7 +407,7 @@ namespace cwg324 { // cwg324: 3.6

namespace cwg326 { // cwg326: 3.1
struct S {};
int test[__is_trivially_constructible(S, const S&) ? 1 : -1];
static_assert(__is_trivially_constructible(S, const S&), "");
}

namespace cwg327 { // cwg327: dup 538
Expand Down Expand Up @@ -653,7 +664,7 @@ namespace cwg339 { // cwg339: 2.8

template<typename T> A<sizeof(f(T()))> make_A();

int a[conv_int<char>::value ? 1 : -1];
static_assert(conv_int<char>::value, "");
bool b = conv_int2<char>(A<1>());
A<1> c = make_A<char>();
}
Expand Down Expand Up @@ -1099,21 +1110,14 @@ namespace cwg364 { // cwg364: yes
#endif

namespace cwg367 { // cwg367: yes
// FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global
// array as being a VLA!
int a[true ? throw 0 : 4];
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
// expected-error@-2 {{variable length array declaration not allowed at file scope}}
int b[true ? 4 : throw 0];
// cxx98-error@-1 {{variable length arrays in C++ are a Clang extension}}
// cxx98-error@-2 {{variable length array folded to constant array as an extension}}
int c[true ? *new int : 4];
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
static_assert(__enable_constant_folding(true ? throw 0 : 4), "");
// expected-error@-1 {{expression is not an integral constant expression}}
static_assert(__enable_constant_folding(true ? 4 : throw 0), "");
static_assert(__enable_constant_folding(true ? *new int : 4), "");
// expected-error@-1 {{expression is not an integral constant expression}}
// expected-note@-2 {{read of uninitialized object is not allowed in a constant expression}}
// expected-error@-3 {{variable length array declaration not allowed at file scope}}
int d[true ? 4 : *new int];
// cxx98-error@-1 {{variable length arrays in C++ are a Clang extension}}
// cxx98-error@-2 {{variable length array folded to constant array as an extension}}
static_assert(__enable_constant_folding(true ? 4 : *new int), "");

}

namespace cwg368 { // cwg368: 3.6
Expand Down Expand Up @@ -1325,7 +1329,7 @@ namespace cwg383 { // cwg383: yes
struct B { ~B(); };
union C { C &operator=(const C&); };
union D { ~D(); };
int check[(__is_pod(A) || __is_pod(B) || __is_pod(C) || __is_pod(D)) ? -1 : 1];
static_assert(!__is_pod(A) && !__is_pod(B) && !__is_pod(C) && !__is_pod(D), "");
}

namespace cwg384 { // cwg384: yes
Expand Down
60 changes: 30 additions & 30 deletions clang/test/CXX/drs/dr4xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++23 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++2c %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets.
__extension__ typedef __SIZE_TYPE__ size_t;

Expand Down Expand Up @@ -217,7 +222,7 @@ namespace cwg407 { // cwg407: 3.8
}

namespace cwg408 { // cwg408: 3.4
template<int N> void g() { int arr[N != 1 ? 1 : -1]; }
template<int N> void g() { static_assert(N != 1, ""); }
template<> void g<2>() { }

template<typename T> struct S {
Expand All @@ -239,7 +244,7 @@ namespace cwg408 { // cwg408: 3.4
};
template<typename T> int R<T>::arr[1];
template<typename T> void R<T>::f() {
int arr[sizeof(arr) != sizeof(int) ? 1 : -1];
static_assert(sizeof(arr) != sizeof(int), "");
}
template<> int R<int>::arr[2];
template void R<int>::f();
Expand Down Expand Up @@ -842,11 +847,10 @@ namespace cwg451 { // cwg451: yes
// expected-warning@-1 {{division by zero is undefined}}
const int b = 1 / 0; // #cwg451-b
// expected-warning@-1 {{division by zero is undefined}}
int arr[b]; // #cwg451-arr
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
static_assert(b, "");
// expected-error@-1 {{expression is not an integral constant expression}}
// expected-note@-2 {{initializer of 'b' is not a constant expression}}
// expected-note@#cwg451-b {{declared here}}
// expected-error@#cwg451-arr {{variable length array declaration not allowed at file scope}}
}

namespace cwg452 { // cwg452: yes
Expand Down Expand Up @@ -876,11 +880,10 @@ namespace cwg456 { // cwg456: yes
namespace cwg457 { // cwg457: yes
const int a = 1;
const volatile int b = 1;
int ax[a];
int bx[b];
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
static_assert(a, "");
static_assert(b, "");
// expected-error@-1 {{expression is not an integral constant expression}}
// expected-note@-2 {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
// expected-error@-3 {{variable length array declaration not allowed at file scope}}

enum E {
ea = a,
Expand Down Expand Up @@ -1276,20 +1279,18 @@ namespace cwg482 { // cwg482: 3.5

namespace cwg483 { // cwg483: yes
namespace climits {
int check1[__SCHAR_MAX__ >= 127 ? 1 : -1];
int check2[__SHRT_MAX__ >= 32767 ? 1 : -1];
int check3[__INT_MAX__ >= 32767 ? 1 : -1];
int check4[__LONG_MAX__ >= 2147483647 ? 1 : -1];
int check5[__LONG_LONG_MAX__ >= 9223372036854775807 ? 1 : -1];
// cxx98-error@-1 {{'long long' is a C++11 extension}}
// cxx98-error@-2 0-1{{'long long' is a C++11 extension}}
static_assert(__SCHAR_MAX__ >= 127, "");
static_assert(__SHRT_MAX__ >= 32767, "");
static_assert(__INT_MAX__ >= 32767, "");
static_assert(__LONG_MAX__ >= 2147483647, "");
static_assert(__LONG_LONG_MAX__ >= 9223372036854775807, "");
}
namespace cstdint {
int check1[__PTRDIFF_WIDTH__ >= 16 ? 1 : -1];
int check2[__SIG_ATOMIC_WIDTH__ >= 8 ? 1 : -1];
int check3[__SIZE_WIDTH__ >= 16 ? 1 : -1];
int check4[__WCHAR_WIDTH__ >= 8 ? 1 : -1];
int check5[__WINT_WIDTH__ >= 16 ? 1 : -1];
static_assert(__PTRDIFF_WIDTH__ >= 16, "");
static_assert(__SIG_ATOMIC_WIDTH__ >= 8, "");
static_assert(__SIZE_WIDTH__ >= 16, "");
static_assert(__WCHAR_WIDTH__ >= 8, "");
static_assert(__WINT_WIDTH__ >= 16, "");
}
}

Expand Down Expand Up @@ -1366,11 +1367,10 @@ namespace cwg486 { // cwg486: yes
namespace cwg487 { // cwg487: yes
enum E { e };
int operator+(int, E); // #cwg487-operator-plus
int i[4 + e]; // #cwg487-i
// expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
static_assert(4 + e, "");
// expected-error@-1 {{expression is not an integral constant expression}}
// since-cxx11-note@-2 {{non-constexpr function 'operator+' cannot be used in a constant expression}}
// since-cxx11-note@#cwg487-operator-plus {{declared here}}
// expected-error@#cwg487-i {{variable length array declaration not allowed at file scope}}
}

namespace cwg488 { // cwg488: yes c++11
Expand Down Expand Up @@ -1485,13 +1485,13 @@ namespace cwg495 { // cwg495: 3.5
namespace cwg496 { // cwg496: sup 2094
struct A { int n; };
struct B { volatile int n; };
int check1[ __is_trivially_copyable(const int) ? 1 : -1];
static_assert(__is_trivially_copyable(const int), "");
// This checks the cwg2094 behavior, not cwg496
int check2[ __is_trivially_copyable(volatile int) ? 1 : -1];
int check3[ __is_trivially_constructible(A, const A&) ? 1 : -1];
int check4[ __is_trivially_constructible(B, const B&) ? 1 : -1];
int check5[ __is_trivially_assignable(A, const A&) ? 1 : -1];
int check6[ __is_trivially_assignable(B, const B&) ? 1 : -1];
static_assert(__is_trivially_copyable(volatile int), "");
static_assert(__is_trivially_constructible(A, const A&), "");
static_assert(__is_trivially_constructible(B, const B&), "");
static_assert(__is_trivially_assignable(A, const A&), "");
static_assert(__is_trivially_assignable(B, const B&), "");
}

namespace cwg497 { // cwg497: sup 253
Expand Down
13 changes: 9 additions & 4 deletions clang/test/CXX/drs/dr5xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

// FIXME: This is included to avoid a diagnostic with no source location
// pointing at the implicit operator new. We can't match such a diagnostic
// with -verify.
Expand Down Expand Up @@ -819,7 +824,7 @@ namespace cwg565 { // cwg565: yes

namespace cwg566 { // cwg566: yes
#if __cplusplus >= 201103L
int check[int(-3.99) == -3 ? 1 : -1];
static_assert(int(-3.99) == -3, "");
#endif
}

Expand All @@ -834,7 +839,7 @@ namespace cwg568 { // cwg568: 3.0 c++11
public:
int n;
};
int check_trivial[__is_trivial(trivial) ? 1 : -1];
static_assert(__is_trivial(trivial), "");

struct std_layout {
std_layout();
Expand All @@ -843,7 +848,7 @@ namespace cwg568 { // cwg568: 3.0 c++11
private:
int n;
};
int check_std_layout[__is_standard_layout(std_layout) ? 1 : -1];
static_assert(__is_standard_layout(std_layout), "");

struct aggregate {
int x;
Expand Down Expand Up @@ -885,7 +890,7 @@ namespace cwg570 { // cwg570: dup 633

namespace cwg572 { // cwg572: yes
enum E { a = 1, b = 2 };
int check[a + b == 3 ? 1 : -1];
static_assert(a + b == 3, "");
}

namespace cwg573 { // cwg573: no
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CXX/drs/dr6xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace cwg608 { // cwg608: yes
struct D : B, C {};
}

int cwg610[-0u == 0u ? 1 : -1]; // cwg610: yes
static_assert(-0u == 0u, ""); // cwg610: yes

namespace cwg611 { // cwg611: yes
int k;
Expand Down Expand Up @@ -190,8 +190,8 @@ namespace cwg613 { // cwg613: yes c++11
}
}

int cwg614_a[(-1) / 2 == 0 ? 1 : -1]; // cwg614: yes
int cwg614_b[(-1) % 2 == -1 ? 1 : -1];
static_assert((-1) / 2 == 0, ""); // cwg614: yes
static_assert((-1) % 2 == -1, "");

namespace cwg615 { // cwg615: yes
int f();
Expand Down
25 changes: 20 additions & 5 deletions clang/test/CodeGen/alias.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
// RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only -DERR %s
// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits -DERR %s 2>&1 | FileCheck %s --check-prefix=FIXIT
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm %s -o - | FileCheck %s

#ifdef ERR
void *f1_ifunc(void) { return nullptr; }
void f1(void) __attribute__((alias("f1_ifunc")));
// expected-error@-1 {{alias must point to a defined variable or function}}
// expected-note@-2 {{must refer to its mangled name}}
// expected-note@-3 {{function by that name is mangled as}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:47}:"alias(\"_Z8f1_ifuncv\")"
// FIXIT: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:47}:"alias(\"_Z8f1_ifuncv\")"

void *f6_resolver_resolver(void) { return 0; }
void *f6_resolver(void) __attribute__((alias("f6_resolver_resolver")));
// expected-error@-1 {{alias must point to a defined variable or function}}
// expected-note@-2 {{must refer to its mangled name}}
// expected-note@-3 {{function by that name is mangled as}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:40-[[@LINE-4]]:69}:"alias(\"_Z20f6_resolver_resolverv\")"
// FIXIT: fix-it:"{{.*}}":{[[@LINE-4]]:40-[[@LINE-4]]:69}:"alias(\"_Z20f6_resolver_resolverv\")"
void f6(void) __attribute__((alias("f6_resolver")));
// expected-error@-1 {{alias must point to a defined variable or function}}
// expected-note@-2 {{must refer to its mangled name}}
// expected-note@-3 {{function by that name is mangled as}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:50}:"alias(\"_Z11f6_resolverv\")"
// FIXIT: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:50}:"alias(\"_Z11f6_resolverv\")"

__attribute__((unused, alias("resolver"), deprecated("hahahaha, isn't C great?")))
void func();
// expected-error@-2 {{alias must point to a defined variable or function}}
// expected-note@-3 {{must refer to its mangled name}}
#endif

// CHECK: @_ZN4libc4log2Ed ={{.*}} alias double (double), ptr @log2
// CHECK: define{{.*}} @log2(
namespace libc { double log2(double x); }
extern "C" double log2(double);
namespace std { using ::log2; }
using std::log2;

namespace libc {
decltype(libc::log2) __log2_impl__ __asm__("log2");
decltype(libc::log2) log2 [[gnu::alias("log2")]];
double __log2_impl__(double x) { return x; }
}
11 changes: 11 additions & 0 deletions clang/test/Sema/recover-expr-gh88008-nocrash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c90

struct S {
int v;
};

struct T; // expected-note {{forward declaration of 'struct T'}}

void gh88008_nocrash(struct T *t) {
struct S s = { .v = t->y }; // expected-error {{incomplete definition of type 'struct T'}}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
// Issue no: 41441
#include <new>
// RUN: %clang --target=x86_64-pc-linux -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s

namespace std {
using size_t = decltype(sizeof(int));
};
void* operator new[](std::size_t, void*) noexcept;

// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 false)
Expand Down
6 changes: 5 additions & 1 deletion flang/cmake/modules/AddFlangOffloadRuntime.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set(FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD "off" CACHE STRING
set(FLANG_OMP_DEVICE_ARCHITECTURES "all" CACHE STRING
"List of OpenMP device architectures to be used to compile the Fortran runtime (e.g. 'gfx1103;sm_90')")

macro(enable_cuda_compilation files)
macro(enable_cuda_compilation name files)
if (FLANG_EXPERIMENTAL_CUDA_RUNTIME)
if (BUILD_SHARED_LIBS)
message(FATAL_ERROR
Expand Down Expand Up @@ -52,6 +52,10 @@ macro(enable_cuda_compilation files)
include_directories(AFTER ${FLANG_LIBCUDACXX_PATH}/include)
add_compile_definitions(RT_USE_LIBCUDACXX=1)
endif()

# Add an OBJECT library consisting of CUDA PTX.
llvm_add_library(${name}PTX OBJECT PARTIAL_SOURCES_INTENDED ${files})
set_property(TARGET obj.${name}PTX PROPERTY CUDA_PTX_COMPILATION ON)
endif()
endmacro()

Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Decimal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ set(sources
)

include(AddFlangOffloadRuntime)
enable_cuda_compilation("${sources}")
enable_cuda_compilation(FortranDecimal "${sources}")
enable_omp_offload_compilation("${sources}")

add_flang_library(FortranDecimal INSTALL_WITH_TOOLCHAIN ${sources})
Expand Down
2 changes: 1 addition & 1 deletion flang/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ set(supported_files
utf.cpp
)

enable_cuda_compilation("${supported_files}")
enable_cuda_compilation(FortranRuntime "${supported_files}")
enable_omp_offload_compilation("${supported_files}")

if (NOT TARGET FortranFloat128Math)
Expand Down
8 changes: 4 additions & 4 deletions flang/test/Driver/msvc-dependent-lib-flags.f90
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
! RUN: %flang -### --target=aarch64-windows-msvc %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=static_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DEBUG
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL-DEBUG
! RUN: %flang -### --target=aarch64-windows-msvc -resource-dir=%S/Inputs/resource_dir %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC
! RUN: %flang -### --target=aarch64-windows-msvc -resource-dir=%S/Inputs/resource_dir -fms-runtime-lib=static_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DEBUG
! RUN: %flang -### --target=aarch64-windows-msvc -resource-dir=%S/Inputs/resource_dir -fms-runtime-lib=dll %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL
! RUN: %flang -### --target=aarch64-windows-msvc -resource-dir=%S/Inputs/resource_dir -fms-runtime-lib=dll_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL-DEBUG

! MSVC: -fc1
! MSVC-SAME: --dependent-lib=clang_rt.builtins.lib
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Semantics/OpenMP/clause-validity01.f90
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@
a = 1.0
!ERROR: COPYPRIVATE clause is not allowed on the END WORKSHARE directive
!$omp end workshare nowait copyprivate(a)
!ERROR: NOWAIT clause is not allowed on the OMP WORKSHARE directive, use it on OMP END WORKSHARE directive
!$omp workshare nowait
!ERROR: NOWAIT clause is not allowed on the WORKSHARE directive, use it on OMP END WORKSHARE directive
!$omp end workshare
!$omp end parallel

Expand Down
10 changes: 0 additions & 10 deletions libc/src/fenv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ add_entrypoint_object(
HDRS
fesetround.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand All @@ -30,7 +29,6 @@ add_entrypoint_object(
HDRS
feclearexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand All @@ -43,7 +41,6 @@ add_entrypoint_object(
HDRS
feraiseexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand All @@ -56,7 +53,6 @@ add_entrypoint_object(
HDRS
fetestexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand All @@ -69,7 +65,6 @@ add_entrypoint_object(
HDRS
fegetenv.h
DEPENDS
libc.hdr.fenv_macros
libc.hdr.types.fenv_t
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
Expand All @@ -83,7 +78,6 @@ add_entrypoint_object(
HDRS
fesetenv.h
DEPENDS
libc.hdr.fenv_macros
libc.hdr.types.fenv_t
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
Expand Down Expand Up @@ -111,7 +105,6 @@ add_entrypoint_object(
HDRS
fesetexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand Down Expand Up @@ -166,7 +159,6 @@ add_entrypoint_object(
HDRS
feenableexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand All @@ -179,7 +171,6 @@ add_entrypoint_object(
HDRS
fedisableexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand All @@ -192,7 +183,6 @@ add_entrypoint_object(
HDRS
fegetexcept.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.FPUtil.fenv_impl
COMPILE_OPTIONS
-O2
Expand Down
2 changes: 1 addition & 1 deletion libc/src/fenv/fegetexceptflag.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_FENV_FEGETEXCEPTFLAG_H
#define LLVM_LIBC_SRC_FENV_FEGETEXCEPTFLAG_H

#include <fenv.h>
#include "hdr/types/fexcept_t.h"

namespace LIBC_NAMESPACE {

Expand Down
2 changes: 1 addition & 1 deletion libc/src/fenv/fesetexceptflag.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_FENV_FESETEXCEPTFLAG_H
#define LLVM_LIBC_SRC_FENV_FESETEXCEPTFLAG_H

#include <fenv.h>
#include "hdr/types/fexcept_t.h"

namespace LIBC_NAMESPACE {

Expand Down
2 changes: 1 addition & 1 deletion libc/src/fenv/feupdateenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/common.h"

#include <fenv.h>
#include "hdr/types/fenv_t.h"

namespace LIBC_NAMESPACE {

Expand Down
6 changes: 3 additions & 3 deletions libclc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ if( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DI
endif()

# Import required tools as targets
foreach( tool clang llvm-as llvm-link opt )
foreach( tool IN ITEMS clang llvm-as llvm-link opt )
find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
add_executable( libclc::${tool} IMPORTED GLOBAL )
set_target_properties( libclc::${tool} PROPERTIES IMPORTED_LOCATION ${LLVM_TOOL_${tool}} )
Expand All @@ -68,7 +68,7 @@ else()
message(FATAL_ERROR "Clang is not enabled, but is required to build libclc in-tree")
endif()

foreach( tool clang llvm-as llvm-link opt )
foreach( tool IN ITEMS clang llvm-as llvm-link opt )
add_executable(libclc::${tool} ALIAS ${tool})
endforeach()
endif()
Expand Down Expand Up @@ -181,7 +181,7 @@ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libclc.pc DESTINATION "${CMAKE_INSTAL
install( DIRECTORY generic/include/clc DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" )

if( ENABLE_RUNTIME_SUBNORMAL )
foreach( file subnormal_use_default subnormal_disable )
foreach( file IN ITEMS subnormal_use_default subnormal_disable )
link_bc(
TARGET ${file}
INPUTS ${PROJECT_SOURCE_DIR}/generic/lib/${file}.ll
Expand Down
1 change: 1 addition & 0 deletions libcxx/.clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ AttributeMacros: [
'_LIBCPP_CONSTEXPR_SINCE_CXX23',
'_LIBCPP_CONSTEXPR',
'_LIBCPP_CONSTINIT',
'_LIBCPP_DEPRECATED_ATOMIC_SYNC',
'_LIBCPP_DEPRECATED_IN_CXX11',
'_LIBCPP_DEPRECATED_IN_CXX14',
'_LIBCPP_DEPRECATED_IN_CXX17',
Expand Down
6 changes: 6 additions & 0 deletions libcxx/docs/BuildingLibcxx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@ libc++ specific options

Toggle the installation of the libc++ headers.

.. option:: LIBCXX_INSTALL_MODULES:BOOL

**Default**: ``OFF``

Toggle the installation of the experimental libc++ module sources.

.. option:: LIBCXX_ENABLE_SHARED:BOOL

**Default**: ``ON``
Expand Down
6 changes: 5 additions & 1 deletion libcxx/docs/ReleaseNotes/19.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ Improvements and New Features
Deprecations and Removals
-------------------------

- The C++20 synchronization library (``<barrier>``, ``<latch>``, ``atomic::wait``, etc.) has been deprecated
in language modes prior to C++20. If you are using these features prior to C++20, please update to ``-std=c++20``.
In LLVM 20, the C++20 synchronization library will be removed entirely in language modes prior to C++20.

- TODO: The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable that was used to enable the safe mode has been deprecated and setting
it triggers an error; use the ``LIBCXX_HARDENING_MODE`` CMake variable with the value ``extensive`` instead. Similarly,
the ``_LIBCPP_ENABLE_ASSERTIONS`` macro has been deprecated (setting it to ``1`` still enables the extensive mode in
Expand All @@ -93,7 +97,7 @@ Deprecations and Removals
- The ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`` and ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION``
macros have been removed in LLVM 19.

- TODO: The ``_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES`` and ``_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES`` macros have
- The ``_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES`` and ``_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES`` macros have
been removed in LLVM 19. C++17 and C++20 removed features can still be re-enabled individually.

- The ``_LIBCPP_INLINE_VISIBILITY`` and ``_VSTD`` macros have been removed in LLVM 19.
Expand Down
12 changes: 0 additions & 12 deletions libcxx/docs/UsingLibcxx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,6 @@ safety annotations.

C++17 Specific Configuration Macros
-----------------------------------
**_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES**:
This macro is used to re-enable all the features removed in C++17. The effect
is equivalent to manually defining each macro listed below.
This macro is deprecated and will be removed in LLVM-19. Use the
individual macros listed below.

**_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
This macro is used to re-enable `auto_ptr`.

Expand All @@ -238,12 +232,6 @@ C++20 Specific Configuration Macros
This macro is used to re-enable the function
``std::shared_ptr<...>::unique()``.

**_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES**:
This macro is used to re-enable all the features removed in C++20. The effect
is equivalent to manually defining each macro listed below.
This macro is deprecated and will be removed in LLVM-19. Use the
individual macros listed below.

**_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**:
This macro is used to re-enable the `argument_type`, `result_type`,
`first_argument_type`, and `second_argument_type` members of class
Expand Down
12 changes: 8 additions & 4 deletions libcxx/include/__atomic/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,22 +462,26 @@ atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __
// atomic_notify_one

template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
__o->notify_one();
}
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
__o->notify_one();
}

// atomic_notify_all

template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
__o->notify_all();
}
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
__o->notify_all();
}

Expand Down
34 changes: 20 additions & 14 deletions libcxx/include/__atomic/atomic_flag.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,26 @@ struct atomic_flag {
__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
}

_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
volatile _NOEXCEPT {
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
std::__atomic_notify_one(*this);
}
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
std::__atomic_notify_one(*this);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
std::__atomic_notify_all(*this);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
std::__atomic_notify_all(*this);
}

#if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
Expand Down Expand Up @@ -141,41 +145,43 @@ inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, m
__o->clear(__m);
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
__o->wait(__v);
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
__o->wait(__v);
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
__o->wait(__v, __m);
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
__o->wait(__v, __m);
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
__o->notify_one();
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
__o->notify_one();
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
__o->notify_all();
}

inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
__o->notify_all();
}

Expand Down
16 changes: 16 additions & 0 deletions libcxx/include/__availability
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@
# define _LIBCPP_AVAILABILITY_HAS_TZDB 1
# define _LIBCPP_AVAILABILITY_TZDB

// These macros determine whether we assume that std::bad_function_call and
// std::bad_expected_access provide a key function in the dylib. This allows
// centralizing their vtable and typeinfo instead of having all TUs provide
// a weak definition that then gets deduplicated.
# define _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION 1
# define _LIBCPP_AVAILABILITY_BAD_FUNCTION_CALL_KEY_FUNCTION
# define _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION 1
# define _LIBCPP_AVAILABILITY_BAD_EXPECTED_ACCESS_KEY_FUNCTION

#elif defined(__APPLE__)

# define _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS \
Expand Down Expand Up @@ -290,6 +299,13 @@
# else
# define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 1
# endif

# define _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION 0
# define _LIBCPP_AVAILABILITY_BAD_FUNCTION_CALL_KEY_FUNCTION __attribute__((unavailable))

# define _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION 0
# define _LIBCPP_AVAILABILITY_BAD_EXPECTED_ACCESS_KEY_FUNCTION __attribute__((unavailable))

#else

// ...New vendors can add availability markup here...
Expand Down
28 changes: 14 additions & 14 deletions libcxx/include/__chrono/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ namespace __formatter {
// small). Therefore a duration uses its own conversion.
template <class _CharT, class _Rep, class _Period>
_LIBCPP_HIDE_FROM_ABI void
__format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_stringstream<_CharT>& __sstr) {
__format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::duration<_Rep, _Period>& __value) {
__sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();

using __duration = chrono::duration<_Rep, _Period>;
Expand Down Expand Up @@ -110,13 +110,13 @@ __format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_strin
}

template <class _CharT, __is_time_point _Tp>
_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) {
__formatter::__format_sub_seconds(__value.time_since_epoch(), __sstr);
_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(basic_stringstream<_CharT>& __sstr, const _Tp& __value) {
__formatter::__format_sub_seconds(__sstr, __value.time_since_epoch());
}

template <class _CharT, class _Duration>
_LIBCPP_HIDE_FROM_ABI void
__format_sub_seconds(const chrono::hh_mm_ss<_Duration>& __value, basic_stringstream<_CharT>& __sstr) {
__format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::hh_mm_ss<_Duration>& __value) {
__sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point();
if constexpr (chrono::treat_as_floating_point_v<typename _Duration::rep>)
std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
Expand All @@ -143,7 +143,7 @@ consteval bool __use_fraction() {
}

template <class _CharT>
_LIBCPP_HIDE_FROM_ABI void __format_year(int __year, basic_stringstream<_CharT>& __sstr) {
_LIBCPP_HIDE_FROM_ABI void __format_year(basic_stringstream<_CharT>& __sstr, int __year) {
if (__year < 0) {
__sstr << _CharT('-');
__year = -__year;
Expand All @@ -159,7 +159,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_year(int __year, basic_stringstream<_CharT>&
}

template <class _CharT>
_LIBCPP_HIDE_FROM_ABI void __format_century(int __year, basic_stringstream<_CharT>& __sstr) {
_LIBCPP_HIDE_FROM_ABI void __format_century(basic_stringstream<_CharT>& __sstr, int __year) {
// TODO FMT Write an issue
// [tab:time.format.spec]
// %C The year divided by 100 using floored division. If the result is a
Expand All @@ -172,7 +172,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_century(int __year, basic_stringstream<_Char

template <class _CharT, class _Tp>
_LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
const _Tp& __value, basic_stringstream<_CharT>& __sstr, basic_string_view<_CharT> __chrono_specs) {
basic_stringstream<_CharT>& __sstr, const _Tp& __value, basic_string_view<_CharT> __chrono_specs) {
tm __t = std::__convert_to_tm<tm>(__value);
const auto& __facet = std::use_facet<time_put<_CharT>>(__sstr.getloc());
for (auto __it = __chrono_specs.begin(); __it != __chrono_specs.end(); ++__it) {
Expand All @@ -196,7 +196,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
// strftime's output is only defined in the range [00, 99].
int __year = __t.tm_year + 1900;
if (__year < 1000 || __year > 9999)
__formatter::__format_century(__year, __sstr);
__formatter::__format_century(__sstr, __year);
else
__facet.put(
{__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
Expand Down Expand Up @@ -242,7 +242,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
__facet.put(
{__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
if constexpr (__use_fraction<_Tp>())
__formatter::__format_sub_seconds(__value, __sstr);
__formatter::__format_sub_seconds(__sstr, __value);
break;

// Unlike time_put and strftime the formatting library requires %Y
Expand Down Expand Up @@ -283,13 +283,13 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
// Depending on the platform's libc the range of supported years is
// limited. Intead of of testing all conditions use the internal
// implementation unconditionally.
__formatter::__format_year(__t.tm_year + 1900, __sstr);
__formatter::__format_year(__sstr, __t.tm_year + 1900);
break;

case _CharT('F'): {
int __year = __t.tm_year + 1900;
if (__year < 1000) {
__formatter::__format_year(__year, __sstr);
__formatter::__format_year(__sstr, __year);
__sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday);
} else
__facet.put(
Expand All @@ -310,7 +310,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
++__it;
__facet.put(
{__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1));
__formatter::__format_sub_seconds(__value, __sstr);
__formatter::__format_sub_seconds(__sstr, __value);
break;
}
}
Expand Down Expand Up @@ -512,7 +512,7 @@ __format_chrono(const _Tp& __value,
if constexpr (chrono::__is_duration<_Tp>::value) {
if (__value < __value.zero())
__sstr << _CharT('-');
__formatter::__format_chrono_using_chrono_specs(chrono::abs(__value), __sstr, __chrono_specs);
__formatter::__format_chrono_using_chrono_specs(__sstr, chrono::abs(__value), __chrono_specs);
// TODO FMT When keeping the precision it will truncate the string.
// Note that the behaviour what the precision does isn't specified.
__specs.__precision_ = -1;
Expand Down Expand Up @@ -556,7 +556,7 @@ __format_chrono(const _Tp& __value,
__sstr << _CharT('-');
}

__formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs);
__formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs);
}
}

Expand Down
60 changes: 13 additions & 47 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,6 @@
# pragma GCC system_header
#endif

#if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
# pragma clang deprecated( \
_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES, \
"_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES is deprecated in LLVM 18 and will be removed in LLVM 19")
#endif
#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
# pragma clang deprecated( \
_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES, \
"_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES is deprecated in LLVM 18 and will be removed in LLVM 19")
#endif

#if defined(__apple_build_version__)
// Given AppleClang XX.Y.Z, _LIBCPP_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403)
# define _LIBCPP_COMPILER_CLANG_BASED
Expand Down Expand Up @@ -120,14 +109,11 @@
# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
// Define a key function for `bad_function_call` in the library, to centralize
// its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies.
# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
// Override the default return value of exception::what() for
// bad_function_call::what() with a string that is specific to
// bad_function_call (see http://wg21.link/LWG2233). This is an ABI break
// because it changes the vtable layout of bad_function_call.
// Override the default return value of exception::what() for bad_function_call::what()
// with a string that is specific to bad_function_call (see http://wg21.link/LWG2233).
// This is an ABI break on platforms that sign and authenticate vtable function pointers
// because it changes the mangling of the virtual function located in the vtable, which
// changes how it gets signed.
# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
// Enable optimized version of __do_get_(un)signed which avoids redundant copies.
# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
Expand Down Expand Up @@ -197,19 +183,6 @@
# if defined(__FreeBSD__) && __FreeBSD__ < 14
# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
# endif
// For XCOFF linkers, we have problems if we see a weak hidden version of a symbol
// in user code (like you get with -fvisibility-inlines-hidden) and then a strong def
// in the library, so we need to always rely on the library version.
# if defined(_AIX)
# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
# endif
# endif

# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2
// Define a key function for `bad_function_call` in the library, to centralize
// its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies.
# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
# endif

// We had some bugs where we use [[no_unique_address]] together with construct_at,
Expand Down Expand Up @@ -972,6 +945,14 @@ typedef __char32_t char32_t;
# define _LIBCPP_DEPRECATED_(m)
# endif

# if _LIBCPP_STD_VER < 20
# define _LIBCPP_DEPRECATED_ATOMIC_SYNC \
_LIBCPP_DEPRECATED_("The C++20 synchronization library has been deprecated prior to C++20. Please update to " \
"using -std=c++20 if you need to use these facilities.")
# else
# define _LIBCPP_DEPRECATED_ATOMIC_SYNC /* nothing */
# endif

# if !defined(_LIBCPP_CXX03_LANG)
# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
# else
Expand Down Expand Up @@ -1238,21 +1219,6 @@ typedef __char32_t char32_t;
# define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__
# endif

# if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES)
# define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
# define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
# define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
# define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
# define _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
# endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES

# if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
# define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
# define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
# define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
# define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES

// clang-format off
# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh\")") _Pragma("push_macro(\"move\")") _Pragma("push_macro(\"erase\")")
# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh\")") _Pragma("pop_macro(\"move\")") _Pragma("pop_macro(\"erase\")")
Expand Down
13 changes: 8 additions & 5 deletions libcxx/include/__expected/bad_expected_access.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H
#define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H

#include <__availability>
#include <__config>
#include <__exception/exception.h>
#include <__utility/move.h>
Expand All @@ -28,9 +29,11 @@ template <class _Err>
class bad_expected_access;

_LIBCPP_DIAGNOSTIC_PUSH
# if !_LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
# endif
template <>
class bad_expected_access<void> : public exception {
class _LIBCPP_EXPORTED_FROM_ABI bad_expected_access<void> : public exception {
protected:
_LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) noexcept = default;
Expand All @@ -40,11 +43,11 @@ class bad_expected_access<void> : public exception {
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default;

public:
// The way this has been designed (by using a class template below) means that we'll already
// have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch
// of work to do. So it is not worth hiding the <void> specialization in the dylib, given that
// it adds deployment target restrictions.
# if _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION
const char* what() const noexcept override;
# else
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; }
# endif
};
_LIBCPP_DIAGNOSTIC_POP

Expand Down
5 changes: 4 additions & 1 deletion libcxx/include/__functional/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define _LIBCPP___FUNCTIONAL_FUNCTION_H

#include <__assert>
#include <__availability>
#include <__config>
#include <__exception/exception.h>
#include <__functional/binary_function.h>
Expand Down Expand Up @@ -55,7 +56,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// bad_function_call

_LIBCPP_DIAGNOSTIC_PUSH
# if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
# endif
class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception {
public:
_LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default;
Expand All @@ -64,7 +67,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception {
// Note that when a key function is not used, every translation unit that uses
// bad_function_call will end up containing a weak definition of the vtable and
// typeinfo.
# ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
# if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION
~bad_function_call() _NOEXCEPT override;
# else
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__fwd/ios.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

_LIBCPP_BEGIN_NAMESPACE_STD

class _LIBCPP_EXPORTED_FROM_ABI ios_base;

template <class _CharT, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS basic_ios;

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/barrier
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public:
# endif // !_LIBCPP_HAS_NO_TREE_BARRIER

template <class _CompletionF = __empty_completion>
class barrier {
class _LIBCPP_DEPRECATED_ATOMIC_SYNC barrier {
__barrier_base<_CompletionF> __b_;

public:
Expand Down
3 changes: 0 additions & 3 deletions libcxx/include/iosfwd
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ template<> struct char_traits<wchar_t>;

template<class T> class allocator;

class ios_base;
template <class charT, class traits = char_traits<charT> > class basic_ios;

template <class charT, class traits = char_traits<charT> > class basic_streambuf;
Expand Down Expand Up @@ -124,8 +123,6 @@ using wosyncstream = basic_osyncstream<wchar_t>; // C++20

_LIBCPP_BEGIN_NAMESPACE_STD

class _LIBCPP_EXPORTED_FROM_ABI ios_base;

template <class _CharT, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS istreambuf_iterator;
template <class _CharT, class _Traits = char_traits<_CharT> >
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/latch
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ _LIBCPP_PUSH_MACROS

_LIBCPP_BEGIN_NAMESPACE_STD

class latch {
class _LIBCPP_DEPRECATED_ATOMIC_SYNC latch {
__atomic_base<ptrdiff_t> __a_;

public:
Expand Down
6 changes: 4 additions & 2 deletions libcxx/include/semaphore
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private:
};

template <ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
class counting_semaphore {
class _LIBCPP_DEPRECATED_ATOMIC_SYNC counting_semaphore {
__atomic_semaphore_base __semaphore_;

public:
Expand Down Expand Up @@ -172,7 +172,9 @@ public:
}
};

using binary_semaphore = counting_semaphore<1>;
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
using binary_semaphore _LIBCPP_DEPRECATED_ATOMIC_SYNC = counting_semaphore<1>;
_LIBCPP_SUPPRESS_DEPRECATED_POP

_LIBCPP_END_NAMESPACE_STD

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@
{'is_defined': True, 'name': '__ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__119bad_expected_accessIvE4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__120__codecvt_utf8_utf16IDiE10do_unshiftER11__mbstate_tPcS4_RS4_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__120__codecvt_utf8_utf16IDiE11do_encodingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNKSt3__120__codecvt_utf8_utf16IDiE13do_max_lengthEv', 'type': 'FUNC'}
Expand Down Expand Up @@ -2073,6 +2074,7 @@
{'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIwLb1EEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__119__shared_weak_countE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__119bad_expected_accessIvEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTINSt3__120__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
Expand Down Expand Up @@ -2264,6 +2266,7 @@
{'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIwLb1EEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__119bad_expected_accessIvEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTSNSt3__13pmr15memory_resourceE', 'size': 0, 'type': 'OBJECT'}
Expand Down Expand Up @@ -2482,6 +2485,7 @@
{'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIwLb1EEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__119__shared_weak_countE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__119bad_expected_accessIvEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
{'is_defined': True, 'name': '_ZNKSt6__ndk118__time_get_storageIcE15__do_date_orderEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk118__time_get_storageIwE15__do_date_orderEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk119__shared_weak_count13__get_deleterERKSt9type_info', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk119bad_expected_accessIvE4whatEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk120__codecvt_utf8_utf16IDiE10do_unshiftER9mbstate_tPcS4_RS4_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk120__codecvt_utf8_utf16IDiE11do_encodingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNKSt6__ndk120__codecvt_utf8_utf16IDiE13do_max_lengthEv', 'type': 'FUNC'}
Expand Down Expand Up @@ -1722,6 +1723,7 @@
{'is_defined': True, 'name': '_ZTINSt6__ndk118__time_get_storageIwEE', 'size': 12, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt6__ndk118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 12, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt6__ndk119__shared_weak_countE', 'size': 24, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt6__ndk119bad_expected_accessIvEE', 'size': 12, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 12, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 12, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTINSt6__ndk120__codecvt_utf8_utf16IDiEE', 'size': 12, 'type': 'OBJECT'}
Expand Down Expand Up @@ -1958,6 +1960,7 @@
{'is_defined': True, 'name': '_ZTSNSt6__ndk118__time_get_storageIwEE', 'size': 35, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt6__ndk118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 72, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt6__ndk119__shared_weak_countE', 'size': 33, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt6__ndk119bad_expected_accessIvEE', 'size': 36, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 73, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 73, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTSNSt6__ndk120__codecvt_utf8_utf16IDiEE', 'size': 38, 'type': 'OBJECT'}
Expand Down Expand Up @@ -2188,6 +2191,7 @@
{'is_defined': True, 'name': '_ZTVNSt6__ndk117moneypunct_bynameIwLb1EEE', 'size': 56, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt6__ndk118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 60, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt6__ndk119__shared_weak_countE', 'size': 28, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt6__ndk119bad_expected_accessIvEE', 'size': 20, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 40, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'size': 40, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZTVNSt6__ndk120__codecvt_utf8_utf16IDiEE', 'size': 48, 'type': 'OBJECT'}
Expand Down
Loading