27 changes: 27 additions & 0 deletions clang/lib/Sema/SemaFunctionEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1133,13 +1133,40 @@ class Analyzer {
return true;
}

bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
ViolationID::ThrowsOrCatchesExceptions,
Finally->getAtFinallyLoc());
return true;
}

bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
ViolationID::AccessesObjCMethodOrProperty,
Msg->getBeginLoc());
return true;
}

bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) {
// Under the hood, @autorelease (potentially?) allocates memory and
// invokes ObjC methods. We don't currently have memory allocation as
// a "language construct" but we do have ObjC messaging, so diagnose that.
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
ViolationID::AccessesObjCMethodOrProperty,
ARP->getBeginLoc());
return true;
}

bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) {
// Under the hood, this calls objc_sync_enter and objc_sync_exit, wrapped
// in a @try/@finally block. Diagnose this generically as "ObjC
// messaging".
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
ViolationID::AccessesObjCMethodOrProperty,
Sync->getBeginLoc());
return true;
}

bool VisitSEHExceptStmt(SEHExceptStmt *Exc) {
diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
ViolationID::ThrowsOrCatchesExceptions,
Expand Down
125 changes: 115 additions & 10 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,18 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
default:
return false;
}
case OpenACCClauseKind::Worker: {
switch (DirectiveKind) {
case OpenACCDirectiveKind::Loop:
case OpenACCDirectiveKind::ParallelLoop:
case OpenACCDirectiveKind::SerialLoop:
case OpenACCDirectiveKind::KernelsLoop:
case OpenACCDirectiveKind::Routine:
return true;
default:
return false;
}
}
}

default:
Expand Down Expand Up @@ -500,7 +512,6 @@ class SemaOpenACCClauseVisitor {

OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) {
switch (Clause.getClauseKind()) {
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector: {
// TODO OpenACC: These are only implemented enough for the 'seq'
// diagnostic, otherwise treats itself as unimplemented. When we
Expand Down Expand Up @@ -1024,6 +1035,75 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
Clause.getEndLoc());
}

OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
if (DiagIfSeqClause(Clause))
return nullptr;

// Restrictions only properly implemented on 'loop' constructs, and it is
// the only construct that can do anything with this, so skip/treat as
// unimplemented for the combined constructs.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
return isNotImplemented();

Expr *IntExpr =
Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr;

if (IntExpr) {
switch (SemaRef.getActiveComputeConstructInfo().Kind) {
case OpenACCDirectiveKind::Invalid:
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid)
<< OpenACCClauseKind::Worker << "num" << /*orphan=*/0;
IntExpr = nullptr;
break;
case OpenACCDirectiveKind::Parallel:
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid)
<< OpenACCClauseKind::Worker << "num" << /*parallel=*/1;
IntExpr = nullptr;
break;
case OpenACCDirectiveKind::Serial:
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid)
<< OpenACCClauseKind::Worker << "num" << /*serial=*/3;
IntExpr = nullptr;
break;
case OpenACCDirectiveKind::Kernels: {
const auto *Itr =
llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses,
llvm::IsaPred<OpenACCNumWorkersClause>);
if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)
<< OpenACCClauseKind::Worker << /*num_workers=*/1;
SemaRef.Diag((*Itr)->getBeginLoc(),
diag::note_acc_previous_clause_here);

IntExpr = nullptr;
}
break;
}
default:
llvm_unreachable("Non compute construct in active compute construct");
}
}

// OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
// contain a loop with a gang or worker clause unless within a nested compute
// region.
if (SemaRef.LoopWorkerClauseLoc.isValid()) {
// This handles the 'inner loop' diagnostic, but we cannot set that we're on
// one of these until we get to the end of the construct.
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
<< OpenACCClauseKind::Worker << OpenACCClauseKind::Worker
<< /*skip kernels construct info*/ 0;
SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
diag::note_acc_previous_clause_here);
return nullptr;
}

return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(),
Clause.getLParenLoc(), IntExpr,
Clause.getEndLoc());
}

OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
if (DiagIfSeqClause(Clause))
Expand Down Expand Up @@ -1061,8 +1141,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
llvm::IsaPred<OpenACCNumGangsClause>);

if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) {
SemaRef.Diag(ER.get()->getBeginLoc(),
diag::err_acc_gang_num_gangs_conflict);
SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_num_arg_conflict)
<< OpenACCClauseKind::Gang << /*num_gangs=*/0;
SemaRef.Diag((*Itr)->getBeginLoc(),
diag::note_acc_previous_clause_here);
continue;
Expand Down Expand Up @@ -1091,12 +1171,28 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(
if (SemaRef.LoopGangClauseOnKernelLoc.isValid()) {
// This handles the 'inner loop' diagnostic, but we cannot set that we're on
// one of these until we get to the end of the construct.
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_gang_inside_gang);
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
<< OpenACCClauseKind::Gang << OpenACCClauseKind::Gang
<< /*kernels construct info*/ 1;
SemaRef.Diag(SemaRef.LoopGangClauseOnKernelLoc,
diag::note_acc_previous_clause_here);
return nullptr;
}

// OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not
// contain a loop with a gang or worker clause unless within a nested compute
// region.
if (SemaRef.LoopWorkerClauseLoc.isValid()) {
// This handles the 'inner loop' diagnostic, but we cannot set that we're on
// one of these until we get to the end of the construct.
SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)
<< OpenACCClauseKind::Gang << OpenACCClauseKind::Worker
<< /*kernels construct info*/ 1;
SemaRef.Diag(SemaRef.LoopWorkerClauseLoc,
diag::note_acc_previous_clause_here);
return nullptr;
}

return OpenACCGangClause::Create(Ctx, Clause.getBeginLoc(),
Clause.getLParenLoc(), GangKinds, IntExprs,
Clause.getEndLoc());
Expand Down Expand Up @@ -1216,6 +1312,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
ArrayRef<OpenACCClause *> Clauses)
: SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),
DirKind(DK), OldLoopGangClauseOnKernelLoc(S.LoopGangClauseOnKernelLoc),
OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),
LoopRAII(SemaRef, /*PreserveDepth=*/false) {
// Compute constructs end up taking their 'loop'.
if (DirKind == OpenACCDirectiveKind::Parallel ||
Expand All @@ -1232,6 +1329,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
//
// Implement the 'unless within a nested compute region' part.
SemaRef.LoopGangClauseOnKernelLoc = {};
SemaRef.LoopWorkerClauseLoc = {};
} else if (DirKind == OpenACCDirectiveKind::Loop) {
SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses);
Expand All @@ -1252,6 +1350,12 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
if (Itr != Clauses.end())
SemaRef.LoopGangClauseOnKernelLoc = (*Itr)->getBeginLoc();
}

if (UnInstClauses.empty()) {
auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>);
if (Itr != Clauses.end())
SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc();
}
}
}

Expand Down Expand Up @@ -1324,6 +1428,7 @@ void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt(
SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;
SemaRef.LoopGangClauseOnKernelLoc = OldLoopGangClauseOnKernelLoc;
SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;

if (DirKind == OpenACCDirectiveKind::Parallel ||
DirKind == OpenACCDirectiveKind::Serial ||
Expand Down Expand Up @@ -1934,8 +2039,8 @@ ExprResult SemaOpenACC::CheckGangExpr(OpenACCGangKind GK, Expr *E) {
// construct, or an orphaned loop construct, the gang clause behaves as
// follows. ... The num argument is not allowed.
case OpenACCGangKind::Num:
Diag(E->getBeginLoc(), diag::err_acc_gang_arg_invalid)
<< GK
Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
<< OpenACCClauseKind::Gang << GK
<< (/*orphan/parallel=*/ActiveComputeConstructInfo.Kind ==
OpenACCDirectiveKind::Parallel
? 1
Expand All @@ -1951,8 +2056,8 @@ ExprResult SemaOpenACC::CheckGangExpr(OpenACCGangKind GK, Expr *E) {
// construct, the gang clause behaves as follows. ... The dim argument is
// not allowed.
case OpenACCGangKind::Dim:
Diag(E->getBeginLoc(), diag::err_acc_gang_arg_invalid)
<< GK << /*kernels=*/2;
Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
<< OpenACCClauseKind::Gang << GK << /*kernels=*/2;
return ExprError();
// OpenACC 3.3 2.9.2: When the parent compute construct is a kernels
// construct, the gang clause behaves as follows. ... An argument with no
Expand All @@ -1975,8 +2080,8 @@ ExprResult SemaOpenACC::CheckGangExpr(OpenACCGangKind GK, Expr *E) {
// too, so we disallow them too.
case OpenACCGangKind::Dim:
case OpenACCGangKind::Num:
Diag(E->getBeginLoc(), diag::err_acc_gang_arg_invalid)
<< GK << /*Kernels=*/3;
Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid)
<< OpenACCClauseKind::Gang << GK << /*Kernels=*/3;
return ExprError();
case OpenACCGangKind::Static:
return CheckGangStaticExpr(*this, E);
Expand Down
23 changes: 18 additions & 5 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1422,8 +1422,12 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
// the implicit object parameter are of the same type.

auto NormalizeQualifiers = [&](const CXXMethodDecl *M, Qualifiers Q) {
if (M->isExplicitObjectMemberFunction())
if (M->isExplicitObjectMemberFunction()) {
auto ThisType = M->getFunctionObjectParameterReferenceType();
if (ThisType.isConstQualified())
Q.removeConst();
return Q;
}

// We do not allow overloading based off of '__restrict'.
Q.removeRestrict();
Expand All @@ -1439,14 +1443,23 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
return Q;
};

auto CompareType = [&](QualType Base, QualType D) {
auto BS = Base.getNonReferenceType().getCanonicalType().split();
auto AreQualifiersEqual = [&](SplitQualType BS, SplitQualType DS) {
BS.Quals = NormalizeQualifiers(OldMethod, BS.Quals);
DS.Quals = NormalizeQualifiers(NewMethod, DS.Quals);

if (OldMethod->isExplicitObjectMemberFunction()) {
BS.Quals.removeVolatile();
DS.Quals.removeVolatile();
}

return BS.Quals == DS.Quals;
};

auto CompareType = [&](QualType Base, QualType D) {
auto BS = Base.getNonReferenceType().getCanonicalType().split();
auto DS = D.getNonReferenceType().getCanonicalType().split();
DS.Quals = NormalizeQualifiers(NewMethod, DS.Quals);

if (BS.Quals != DS.Quals)
if (!AreQualifiersEqual(BS, DS))
return false;

if (OldMethod->isImplicitObjectMemberFunction() &&
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaStmtAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,10 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
case ParsedAttr::AT_Annotate:
return S.CreateAnnotationAttr(A);
default:
if (Attr *AT = nullptr; A.getInfo().handleStmtAttribute(S, St, A, AT) !=
ParsedAttrInfo::NotHandled) {
return AT;
}
// N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
// declaration attribute is not written on a statement, but this code is
// needed for attributes in Attr.td that do not list any subjects.
Expand Down
9 changes: 4 additions & 5 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4057,11 +4057,10 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
// keep track of these diagnostics. They'll be emitted if this specialization
// is actually used.
if (Info.diag_begin() != Info.diag_end()) {
SuppressedDiagnosticsMap::iterator
Pos = SuppressedDiagnostics.find(Specialization->getCanonicalDecl());
if (Pos == SuppressedDiagnostics.end())
SuppressedDiagnostics[Specialization->getCanonicalDecl()]
.append(Info.diag_begin(), Info.diag_end());
auto [Pos, Inserted] =
SuppressedDiagnostics.try_emplace(Specialization->getCanonicalDecl());
if (Inserted)
Pos->second.append(Info.diag_begin(), Info.diag_end());
}

return TemplateDeductionResult::Success;
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -11787,6 +11787,34 @@ void OpenACCClauseTransform<Derived>::VisitAsyncClause(
: nullptr,
ParsedClause.getEndLoc());
}

template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitWorkerClause(
const OpenACCWorkerClause &C) {
if (C.hasIntExpr()) {
// restrictions on this expression are all "does it exist in certain
// situations" that are not possible to be dependent, so the only check we
// have is that it transforms, and is an int expression.
ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
if (!Res.isUsable())
return;

Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
C.getClauseKind(),
C.getBeginLoc(), Res.get());
if (!Res.isUsable())
return;
ParsedClause.setIntExprDetails(Res.get());
}

NewClause = OpenACCWorkerClause::Create(
Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
ParsedClause.getLParenLoc(),
ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
: nullptr,
ParsedClause.getEndLoc());
}

template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitWaitClause(
const OpenACCWaitClause &C) {
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12339,10 +12339,15 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
return OpenACCGangClause::Create(getContext(), BeginLoc, LParenLoc,
GangKinds, Exprs, EndLoc);
}
case OpenACCClauseKind::Worker: {
SourceLocation LParenLoc = readSourceLocation();
Expr *WorkerExpr = readBool() ? readSubExpr() : nullptr;
return OpenACCWorkerClause::Create(getContext(), BeginLoc, LParenLoc,
WorkerExpr, EndLoc);
}

case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::UseDevice:
Expand Down
9 changes: 8 additions & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8192,10 +8192,17 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
}
return;
}
case OpenACCClauseKind::Worker: {
const auto *WC = cast<OpenACCWorkerClause>(C);
writeSourceLocation(WC->getLParenLoc());
writeBool(WC->hasIntExpr());
if (WC->hasIntExpr())
AddStmt(const_cast<Expr *>(WC->getIntExpr()));
return;
}

case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::UseDevice:
Expand Down
39 changes: 39 additions & 0 deletions clang/test/AST/ast-print-openacc-loop-construct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,43 @@ void foo() {
#pragma acc serial
#pragma acc loop gang
for(;;);

// CHECK: #pragma acc loop worker
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc parallel
#pragma acc loop worker
for(;;);

// CHECK: #pragma acc parallel
// CHECK-NEXT: #pragma acc loop worker
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc parallel
#pragma acc loop worker
for(;;);

// CHECK: #pragma acc serial
// CHECK-NEXT: #pragma acc loop worker
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc serial
#pragma acc loop worker
for(;;);

// CHECK: #pragma acc kernels
// CHECK-NEXT: #pragma acc loop worker(num: 5)
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc kernels
#pragma acc loop worker(5)
for(;;);

// CHECK: #pragma acc kernels
// CHECK-NEXT: #pragma acc loop worker(num: 5)
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc kernels
#pragma acc loop worker(num:5)
for(;;);
}
104 changes: 104 additions & 0 deletions clang/test/C/C2y/n3298.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// RUN: %clang_cc1 -verify=ped -std=c23 -Wall -pedantic %s
// RUN: %clang_cc1 -verify=yay -std=c2y -Wall -pedantic %s
// RUN: %clang_cc1 -verify=pre -std=c2y -Wpre-c2y-compat -Wall -pedantic %s
// RUN: %clang_cc1 -verify=gnu -Wall -Wgnu -x c++ %s
// RUN: %clang_cc1 -verify=yay -Wall -Wgnu -Wno-gnu-imaginary-constant -x c++ %s


/* WG14 N3298: Yes
* Introduce complex literals v. 2
*
* This introduces two suffixes for making complex literals: i and j (and I and
* J), which can be combined in any order with the other floating literal
* suffixes.
*
* We support these suffixes in older language modes as a conforming extension.
* It used to be a GNU extension, but now it's a C2y extension.
*/

// yay-no-diagnostics

static_assert(_Generic(12.0i, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fi, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0li, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0if, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0il, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

static_assert(_Generic(12.0I, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fI, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0lI, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0If, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0Il, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

static_assert(_Generic(12.0j, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fj, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0lj, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0jf, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0jl, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

static_assert(_Generic(12.0J, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fJ, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0lJ, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0Jf, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0Jl, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

1 change: 1 addition & 0 deletions clang/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ if( NOT CLANG_BUILT_STANDALONE )
llvm-dwarfdump
llvm-ifs
llvm-lto2
llvm-mc
llvm-modextract
llvm-nm
llvm-objcopy
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ vint32m1_t test_vr(vint32m1_t a, vint32m1_t b) {
return ret;
}

vint32m1_t test_vd(vint32m1_t a, vint32m1_t b) {
// CHECK-LABEL: define{{.*}} @test_vd
// CHECK: %0 = tail call <vscale x 2 x i32> asm sideeffect "vadd.vv $0, $1, $2", "=^vd,^vd,^vd"(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b)
vint32m1_t ret;
asm volatile ("vadd.vv %0, %1, %2" : "=vd"(ret) : "vd"(a), "vd"(b));
return ret;
}

vbool1_t test_vm(vbool1_t a, vbool1_t b) {
// CHECK-LABEL: define{{.*}} @test_vm
// CHECK: %0 = tail call <vscale x 64 x i1> asm sideeffect "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"(<vscale x 64 x i1> %a, <vscale x 64 x i1> %b)
Expand Down
61 changes: 60 additions & 1 deletion clang/test/CodeGen/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ int main(void) {
P(issignaling, (1.));
P(isfpclass, (1., 1));

Q(fmaximum_num, (1.0, 2.0));
Q(fmaximum_numf, (1.0, 2.0));
Q(fmaximum_numl, (1.0, 2.0));
Q(fminimum_num, (1.0, 2.0));
Q(fminimum_numf, (1.0, 2.0));
Q(fminimum_numl, (1.0, 2.0));

// Bitwise & Numeric Functions

P(abs, (N));
Expand Down Expand Up @@ -305,7 +312,7 @@ void test_float_builtins(__fp16 *H, float F, double D, long double LD) {
}

// CHECK-LABEL: define{{.*}} void @test_float_builtin_ops
void test_float_builtin_ops(float F, double D, long double LD) {
void test_float_builtin_ops(float F, double D, long double LD, int I) {
volatile float resf;
volatile double resd;
volatile long double resld;
Expand Down Expand Up @@ -353,6 +360,58 @@ void test_float_builtin_ops(float F, double D, long double LD) {
resld = __builtin_fmaxl(LD, LD);
// CHECK: call x86_fp80 @llvm.maxnum.f80

resf = __builtin_fminimum_numf(F, F);
// CHECK: call float @llvm.minimumnum.f32

resf = __builtin_fminimum_numf(I, I);
// CHECK: sitofp i32 {{%[0-9]+}} to float
// CHECK: sitofp i32 {{%[0-9]+}} to float
// CHECK: call float @llvm.minimumnum.f32

resf = __builtin_fminimum_numf(1.0, 2.0);
// CHECK: store volatile float 1.000000e+00, ptr %resf

resd = __builtin_fminimum_num(D, D);
// CHECK: call double @llvm.minimumnum.f64

resd = __builtin_fminimum_num(I, I);
// CHECK: sitofp i32 {{%[0-9]+}} to double
// CHECK: sitofp i32 {{%[0-9]+}} to double
// CHECK: call double @llvm.minimumnum.f64

resd = __builtin_fminimum_num(1.0, 2.0);
// CHECK: store volatile double 1.000000e+00, ptr %resd

//FIXME: __builtin_fminimum_numl is not supported well yet.
resld = __builtin_fminimum_numl(1.0, 2.0);
// CHECK: store volatile x86_fp80 0xK3FFF8000000000000000, ptr %resld, align 16

resf = __builtin_fmaximum_numf(F, F);
// CHECK: call float @llvm.maximumnum.f32

resf = __builtin_fmaximum_numf(I, I);
// CHECK: sitofp i32 {{%[0-9]+}} to float
// CHECK: sitofp i32 {{%[0-9]+}} to float
// CHECK: call float @llvm.maximumnum.f32

resf = __builtin_fmaximum_numf(1.0, 2.0);
// CHECK: store volatile float 2.000000e+00, ptr %resf

resd = __builtin_fmaximum_num(D, D);
// CHECK: call double @llvm.maximumnum.f64

resd = __builtin_fmaximum_num(I, I);
// CHECK: sitofp i32 {{%[0-9]+}} to double
// CHECK: sitofp i32 {{%[0-9]+}} to double
// CHECK: call double @llvm.maximumnum.f64

resd = __builtin_fmaximum_num(1.0, 2.0);
// CHECK: store volatile double 2.000000e+00, ptr %resd

//FIXME: __builtin_fmaximum_numl is not supported well yet.
resld = __builtin_fmaximum_numl(1.0, 2.0);
// CHECK: store volatile x86_fp80 0xK40008000000000000000, ptr %resld, align 16

resf = __builtin_fabsf(F);
// CHECK: call float @llvm.fabs.f32

Expand Down
33 changes: 33 additions & 0 deletions clang/test/CodeGen/fmaxfmin-invalid-arguments-type.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: not %clang_cc1 -triple x86_64 %s -fsyntax-only -verify 2>&1 | FileCheck %s --check-prefix=CHECK-ERR

float fminimum_numf (float, float);
double fminimum_num (double, double);
long double fminimum_numl (long double, long double);
float fmaximum_numf (float, float);
double fmaximum_num (double, double);
long double fmaximum_numl (long double, long double);

// CHECK-ERR: passing 'char *' to parameter of incompatible type 'float'
float fmin1(char *a, char *b) {
return fminimum_numf(a, b);
}
// CHECK-ERR: passing 'char *' to parameter of incompatible type 'double'
float fmin2(char *a, char *b) {
return fminimum_num(a, b);
}
// CHECK-ERR: passing 'char *' to parameter of incompatible type 'long double'
float fmin3(char *a, char *b) {
return fminimum_numl(a, b);
}
// CHECK-ERR: passing 'char *' to parameter of incompatible type 'float'
float fmax1(char *a, char *b) {
return fmaximum_numf(a, b);
}
// CHECK-ERR: passing 'char *' to parameter of incompatible type 'double'
float fmax2(char *a, char *b) {
return fmaximum_num(a, b);
}
// CHECK-ERR: passing 'char *' to parameter of incompatible type 'long double'
float fmax3(char *a, char *b) {
return fmaximum_numl(a, b);
}
22 changes: 17 additions & 5 deletions clang/test/CodeGen/math-libcalls.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm %s | FileCheck %s --check-prefix=NO__ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s --check-prefix=NO__ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -ffp-exception-behavior=maytrap %s | FileCheck %s --check-prefix=HAS_MAYTRAP
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm %s | FileCheck %s --check-prefixes=COMMON,NO__ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefixes=COMMON,HAS_ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s --check-prefixes=COMMON,NO__ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s --check-prefixes=COMMON,HAS_ERRNO
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -ffp-exception-behavior=maytrap %s | FileCheck %s --check-prefixes=COMMON,HAS_MAYTRAP
// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN

Expand Down Expand Up @@ -372,6 +372,18 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
// HAS_MAYTRAP: declare float @llvm.experimental.constrained.minnum.f32(
// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.minnum.f80(

fmaximum_num(*d,*d); fmaximum_numf(f,f); fmaximum_numl(*l,*l);

// COMMON: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
// COMMON: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
// COMMON: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]

fminimum_num(*d,*d); fminimum_numf(f,f); fminimum_numl(*l,*l);

// COMMON: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
// COMMON: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
// COMMON: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]

hypot(f,f); hypotf(f,f); hypotl(f,f);

// NO__ERRNO: declare double @hypot(double noundef, double noundef) [[READNONE]]
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Driver/Xlinker-args.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/// -T is reordered to the last to make sure -L takes precedence.
// RUN: %clang -target x86_64-pc-linux-gnu -### \
// RUN: -e _start -T a.lds -Xlinker one -Xlinker --no-demangle \
// RUN: -e _start -T a.lds -t -Xlinker one -Xlinker --no-demangle \
// RUN: -Wl,two,--no-demangle,three -Xlinker four -z five -r %s 2> %t
// RUN: FileCheck -check-prefix=LINUX < %t %s

Expand All @@ -23,7 +23,7 @@

// DARWIN-NOT: --no-demangle
// DARWIN: "one" "two" "three" "four" "-z" "five" "-r"
// LINUX: "--no-demangle" "-e" "_start" "one" "two" "three" "four" "-z" "five" "-r" {{.*}} "-T" "a.lds"
// LINUX: "--no-demangle" "-e" "_start" "one" "two" "three" "four" "-z" "five" "-r" {{.*}} "-T" "a.lds" "-t"
// MINGW: "--no-demangle"
// AIX: "-b" "one" "-b" "two"

Expand Down
2 changes: 2 additions & 0 deletions clang/test/Driver/arm-cortex-cpus-2.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,10 @@
// CHECK-CPUV8MBASE: "-cc1"{{.*}} "-triple" "thumbv8m.base-

// RUN: %clang -target arm -mcpu=cortex-m33 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M33 %s
// RUN: %clang -target arm -mcpu=star-mc1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-STAR-MC1 %s
// RUN: %clang -target arm -mcpu=cortex-m35p -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M35P %s
// CHECK-CORTEX-M33: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "cortex-m33"
// CHECK-STAR-MC1: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "star-mc1"
// CHECK-CORTEX-M35P: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "cortex-m35p"

// RUN: %clang -target arm -mcpu=cortex-m55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M55 %s
Expand Down
5 changes: 2 additions & 3 deletions clang/test/Driver/avr-mmcu.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// A test for the propagation of the -mmcu option to -cc1 and -cc1as

// RUN: %clang -### --target=avr -mmcu=attiny11 -save-temps %s 2>&1 | FileCheck -check-prefix=CHECK0 %s
// CHECK0: "-cc1" {{.*}} "-target-cpu" "attiny11"
// CHECK0: "-cc1as" {{.*}} "-target-cpu" "attiny11"
// RUN: not %clang -### --target=avr -mmcu=attiny11 %s 2>&1 | FileCheck -check-prefix=CHECK0 %s
// CHECK0: error: '-mmcu=attiny11' invalid for input of type c/c++

// RUN: %clang -### --target=avr -mmcu=at90s2313 -save-temps %s 2>&1 | FileCheck -check-prefix=CHECK1 %s
// CHECK1: "-cc1" {{.*}} "-target-cpu" "at90s2313"
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Driver/hip-link-save-temps.hip
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
// CHECK-NOT: {{".*/opt"}}
// CHECK-NOT: {{".*/llc"}}
// CHECK: "{{.*lld.*}}" {{.*}} "-plugin-opt=-amdgpu-internalize-symbols"
// CHECK-SAME: "-o" "a.out-hip-amdgcn-amd-amdhsa-gfx900" "obj1-hip-amdgcn-amd-amdhsa-gfx900.o" "obj2-hip-amdgcn-amd-amdhsa-gfx900.o"
// CHECK-SAME: "-o" "[[HIPFB1:.+]]" "obj1-hip-amdgcn-amd-amdhsa-gfx900.o" "obj2-hip-amdgcn-amd-amdhsa-gfx900.o"
// CHECK: "{{.*lld.*}}" {{.*}} "-plugin-opt=-amdgpu-internalize-symbols"
// CHECK-SAME: "-o" "a.out-hip-amdgcn-amd-amdhsa-gfx906" "obj1-hip-amdgcn-amd-amdhsa-gfx906.o" "obj2-hip-amdgcn-amd-amdhsa-gfx906.o"
// CHECK: {{".*llvm-mc.*"}} "-o" "[[OBJBUNDLE:.*.o]]" "{{.*}}.mcin" "--filetype=obj"
// CHECK-SAME: "-o" "[[HIPFB2:.+]]" "obj1-hip-amdgcn-amd-amdhsa-gfx906.o" "obj2-hip-amdgcn-amd-amdhsa-gfx906.o"
// CHECK: "{{.*clang.*}}" "-target" "x86_64-unknown-linux-gnu" "-o" "[[OBJBUNDLE:.+.o]]" "-x" "assembler" "{{.*}}.mcin" "-c"
// OUT: "{{.*ld.*}}" {{.*}} "-o" "executable" {{.*}} "[[OBJBUNDLE]]"
// NOUT: "{{.*ld.*}}" {{.*}} "-o" "a.out" {{.*}} "[[OBJBUNDLE]]"
// SLO: "{{.*llvm-ar.*}}" "rcsD" "libTest.a" {{.*}} "[[OBJBUNDLE]]"
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Driver/hip-partial-link.hip
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
// LD-R: "{{.*}}/clang-offload-bundler" {{.*}}-unbundle
// LD-R: "{{.*}}/lld" -flavor gnu -m elf64_amdgpu
// LD-R: "{{.*}}/clang-offload-bundler"
// LD-R: "{{.*}}/llvm-mc" -triple x86_64-unknown-linux-gnu
// LD-R: "{{.*}}/clang{{.*}}" -target x86_64-unknown-linux-gnu
// LD-R: "{{.*}}/ld.lld" {{.*}} -r

// RUN: llvm-nm %t.lib.o | FileCheck -check-prefix=OBJ %s
Expand Down Expand Up @@ -65,7 +65,7 @@
// STATIC: "{{.*}}/clang-offload-bundler" {{.*}}-unbundle
// STATIC: "{{.*}}/lld" -flavor gnu -m elf64_amdgpu
// STATIC: "{{.*}}/clang-offload-bundler"
// STATIC: "{{.*}}/llvm-mc" -triple x86_64-unknown-linux-gnu
// STATIC: "{{.*}}/clang{{.*}}" -target x86_64-unknown-linux-gnu
// STATIC: "{{.*}}/llvm-ar"

// RUN: %clang -v --target=x86_64-unknown-linux-gnu --no-offload-new-driver \
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/hip-save-temps.hip
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
// RDCC: "{{.*clang.*}}" "-cc1as" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.o"
// RDCC: "{{.*clang-offload-bundler.*}}" {{.*}} "-output=hip-save-temps.o"
// RDCL: "{{.*clang-offload-bundler.*}}" {{.*}} "-output=hip-save-temps-hip-amdgcn-amd-amdhsa.hipfb"
// RDCL: {{.*}}llvm-mc{{.*}}"-o" "hip-save-temps-hip-amdgcn-amd-amdhsa.o" "hip-save-temps-hip-amdgcn-amd-amdhsa.mcin" "--filetype=obj"
// RDCL: "{{.*clang.*}}" "-target" "x86_64-unknown-linux-gnu" "-o" "{{.*}}.o" "-x" "assembler" "{{.*}}.mcin" "-c"

// -fno-gpu-rdc host object path
// NORDC: "{{.*clang.*}}" "-cc1" {{.*}} "-E" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.hipi"
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Driver/hip-toolchain-rdc-separate.hip
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@
// LINK-BUNDLE-SAME: "-input={{.*}}" "-input=[[IMG_DEV1]]" "-input=[[IMG_DEV2]]" "-output=[[BUNDLE:.*]]"
// LINK-NOBUNDLE-NOT: {{".*clang-offload-bundler"}} "-type=o"

// LINK-EMBED: {{".*llvm-mc.*"}} "-o" "[[OBJBUNDLE:.*o]]" "{{.*}}.mcin" "--filetype=obj"
// LINK-NOEMBED-NOT: {{".*llvm-mc.*"}} "-o"
// LINK-EMBED: {{".*clang.*"}} "-o" "[[OBJBUNDLE:.*o]]" "{{.*}}.mcin"
// LINK-NOEMBED-NOT: {{".*clang.*"}} "-o"

// LINK-EMBED: [[LD:".*ld.*"]] {{.*}} "-o" "a.out" {{.*}} "[[A_OBJ_HOST]]"
// LINK-EMBED-SAME: "[[B_OBJ_HOST]]" "[[OBJBUNDLE]]"
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/hip-toolchain-rdc-static-lib.hip
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@
// CHECK-SAME: "-targets={{.*}},hipv4-amdgcn-amd-amdhsa--gfx803,hipv4-amdgcn-amd-amdhsa--gfx900"
// CHECK-SAME: "-input=[[IMG_DEV1]]" "-input=[[IMG_DEV2]]" "-output=[[BUNDLE:.*hipfb]]"

// CHECK: [[MC:".*llvm-mc.*"]] "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin" "--filetype=obj"
// CHECK: [[MC:".*clang.*"]] "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"

// CHECK: [[AR:".*llvm-ar.*"]] "rcsD" "{{.*}}.out" [[A_OBJ_HOST]] [[B_OBJ_HOST]] [[OBJBUNDLE]]
2 changes: 1 addition & 1 deletion clang/test/Driver/hip-toolchain-rdc.hip
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
// CHECK-SAME: "-targets={{.*}},hipv4-amdgcn-amd-amdhsa--gfx803,hipv4-amdgcn-amd-amdhsa--gfx900"
// CHECK-SAME: "-input={{.*}}" "-input=[[IMG_DEV1]]" "-input=[[IMG_DEV2]]" "-output=[[BUNDLE]]"

// CHECK: [[MC:".*llvm-mc.*"]] "-triple" [[HOST]] "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin" "--filetype=obj"
// CHECK: [[MC:".*clang.*"]] "-target" [[HOST]] "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"

// output the executable
// LNX: [[LD:".*ld.*"]] {{.*}}"-o" "a.out" {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]] [[OBJBUNDLE]]
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/hip-unbundle-preproc.hipi
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
// RDC: {{".*clang.*"}} "-cc1" {{.*}}"-target-cpu" "gfx803" {{.*}}"-o" "[[DEV_BC:.*bc]]" {{.*}}"[[DEV_PP]]"
// RDC: {{".*lld.*"}} {{.*}}"-o" "[[DEV_ISA:.*]]" "[[DEV_BC]]"
// RDC: {{".*clang-offload-bundler.*"}} {{.*}}"-input={{.*}}" "-input=[[DEV_ISA]]" "-output=[[FATBIN:.*]]"
// RDC: {{".*llvm-mc.*"}} "-o" "[[FATBIN_O:.*o]]"
// RDC: {{".*clang.*"}} "-o" "[[FATBIN_O:.*o]]"
// RDC: {{".*ld.*"}} {{.*}}"[[HOST_O]]" "[[FATBIN_O]]"
3 changes: 1 addition & 2 deletions clang/test/Driver/hipspv-toolchain-rdc.hip
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@
// CHECK-SAME: "-targets={{.*}},hip-spirv64----generic"
// CHECK-SAME: "-input=/dev/null" "-input=[[AB_SPIRV]]"
// CHECK-SAME: "-output=[[AB_FATBIN:.*hipfb]]"
// CHECK: {{".*llvm-mc.*"}} "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"
// CHECK-SAME: "--filetype=obj"
// CHECK: {{".*clang.*"}} "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"

// Output the executable
// CHECK: {{".*ld.*"}} {{.*}}"-o" "a.out" {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]]
Expand Down
52 changes: 45 additions & 7 deletions clang/test/Frontend/plugin-attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,57 @@
// REQUIRES: plugins, examples
//--- good_attr.cpp
// expected-no-diagnostics
void fn1a() __attribute__((example)) {}
[[example]] void fn1b() {}
[[plugin::example]] void fn1c() {}
void fn2() __attribute__((example("somestring", 1, 2.0))) {}
// CHECK-COUNT-4: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} "example"
void fn1a() __attribute__((example)) {
__attribute__((example)) for (int i = 0; i < 9; ++i) {}
}
[[example]] void fn1b() {
[[example]] for (int i = 0; i < 9; ++i) {}
}
[[plugin::example]] void fn1c() {
[[plugin::example]] for (int i = 0; i < 9; ++i) {}
}
void fn2() __attribute__((example("somestring", 1, 2.0))) {
__attribute__((example("abc", 3, 4.0))) for (int i = 0; i < 9; ++i) {}
}
template <int N> void template_fn() __attribute__((example("template", N))) {
__attribute__((example("def", N + 1))) for (int i = 0; i < 9; ++i) {}
}
void fn3() { template_fn<5>(); }
// CHECK: -AttributedStmt 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}}
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -AttributedStmt 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}}
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -AttributedStmt 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}}
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -AttributedStmt 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}}
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "abc"
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 3
// CHECK: -FloatingLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'double' 4.000000e+00
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "somestring"
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 1
// CHECK: -FloatingLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'double' 2.000000e+00
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} Implicit "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "def"
// CHECK: -BinaryOperator 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' '+'
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} 'int' 5
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 1
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "template"
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 5

//--- bad_attr.cpp
int var1 __attribute__((example("otherstring"))) = 1; // expected-warning {{'example' attribute only applies to functions}}
class Example {
void __attribute__((example)) fn3(); // expected-error {{'example' attribute only allowed at file scope}}
};
void fn4() __attribute__((example(123))) { } // expected-error {{first argument to the 'example' attribute must be a string literal}}
void fn5() __attribute__((example("a","b", 3, 4.0))) { } // expected-error {{'example' attribute only accepts at most three arguments}}
void fn4() __attribute__((example(123))) { // expected-error {{first argument to the 'example' attribute must be a string literal}}
__attribute__((example("somestring"))) while (true); // expected-warning {{'example' attribute only applies to for loop statements}}
}
void fn5() __attribute__((example("a","b", 3, 4.0))) { // expected-error {{'example' attribute only accepts at most three arguments}}
__attribute__((example("a","b", 3, 4.0))) for (int i = 0; i < 10; ++i) {} // expected-error {{'example' attribute only accepts at most three arguments}}
}
12 changes: 2 additions & 10 deletions clang/test/Lexer/gnu-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL \
// RUN: -Wgnu-zero-variadic-macro-arguments \
// RUN: -Wgnu-imaginary-constant -Wgnu-zero-line-directive
// RUN: -Wgnu-zero-line-directive
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
// RUN: -Wno-gnu-zero-variadic-macro-arguments \
// RUN: -Wno-gnu-imaginary-constant -Wno-gnu-zero-line-directive
// RUN: -Wno-gnu-zero-line-directive
// Additional disabled tests:
// %clang_cc1 -fsyntax-only -verify %s -DZEROARGS -Wgnu-zero-variadic-macro-arguments
// %clang_cc1 -fsyntax-only -verify %s -DIMAGINARYCONST -Wgnu-imaginary-constant
// %clang_cc1 -fsyntax-only -verify %s -DLINE0 -Wgnu-zero-line-directive

#if NONE
Expand All @@ -28,13 +27,6 @@ void foo( const char* c )
}


#if ALL || IMAGINARYCONST
// expected-warning@+3 {{imaginary constants are a GNU extension}}
#endif

float _Complex c = 1.if;


// This case is handled differently because lit has a bug whereby #line 0 is reported to be on line 4294967295
// http://llvm.org/bugs/show_bug.cgi?id=16952
#if ALL || LINE0
Expand Down
1 change: 1 addition & 0 deletions clang/test/Misc/target-invalid-cpu-note/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
// CHECK-SAME: {{^}}, cortex-m7
// CHECK-SAME: {{^}}, cortex-m23
// CHECK-SAME: {{^}}, cortex-m33
// CHECK-SAME: {{^}}, star-mc1
// CHECK-SAME: {{^}}, cortex-m35p
// CHECK-SAME: {{^}}, cortex-m55
// CHECK-SAME: {{^}}, cortex-m85
Expand Down
19 changes: 9 additions & 10 deletions clang/test/ParserOpenACC/parse-clauses.c
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,6 @@ void IntExprParsing() {
#pragma acc loop vector(length:returns_int())
for(;;);

// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc loop worker
for(;;);
// expected-error@+1{{expected expression}}
Expand All @@ -959,8 +958,8 @@ void IntExprParsing() {
// expected-error@+1{{expected expression}}
#pragma acc loop worker(invalid:)
for(;;);
// expected-error@+2{{invalid tag 'invalid' on 'worker' clause}}
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc kernels
// expected-error@+1{{invalid tag 'invalid' on 'worker' clause}}
#pragma acc loop worker(invalid:5)
for(;;);
// expected-error@+1{{expected expression}}
Expand All @@ -983,21 +982,21 @@ void IntExprParsing() {
// expected-note@+1{{to match this '('}}
#pragma acc loop worker(length:6,4)
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc kernels
#pragma acc loop worker(5)
for(;;);
// expected-error@+2{{invalid tag 'length' on 'worker' clause}}
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc kernels
// expected-error@+1{{invalid tag 'length' on 'worker' clause}}
#pragma acc loop worker(length:5)
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc kernels
#pragma acc loop worker(num:5)
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc kernels
#pragma acc loop worker(returns_int())
for(;;);
// expected-error@+2{{invalid tag 'length' on 'worker' clause}}
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc kernels
// expected-error@+1{{invalid tag 'length' on 'worker' clause}}
#pragma acc loop worker(length:returns_int())
for(;;);
}
Expand Down
12 changes: 11 additions & 1 deletion clang/test/Preprocessor/feature_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,17 @@

// Check __has_constexpr_builtin
#if !__has_constexpr_builtin(__builtin_fmax) || \
!__has_constexpr_builtin(__builtin_fmin)
!__has_constexpr_builtin(__builtin_fmin) || \
!__has_constexpr_builtin(__builtin_fmaximum_num) || \
!__has_constexpr_builtin(__builtin_fminimum_num)
#error Clang should have these constexpr builtins
#endif

#if !__has_constexpr_builtin(__builtin_convertvector)
#error Clang should have these constexpr builtins
#endif

#if !__has_constexpr_builtin(__builtin_shufflevector)
#error Clang should have these constexpr builtins
#endif

Expand Down
12 changes: 12 additions & 0 deletions clang/test/Preprocessor/time64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 -E -dM -triple=i686-pc-linux-gnu /dev/null | FileCheck -match-full-lines -check-prefix TIME32 %s
// RUN: %clang_cc1 -E -dM -triple=i686-pc-linux-gnut64 /dev/null | FileCheck -match-full-lines -check-prefix TIME64 %s
// RUN: %clang_cc1 -E -dM -triple=armv5tel-softfloat-linux-gnueabi /dev/null | FileCheck -match-full-lines -check-prefix TIME32 %s
// RUN: %clang_cc1 -E -dM -triple=armv5tel-softfloat-linux-gnueabit64 /dev/null | FileCheck -match-full-lines -check-prefix TIME64 %s
// RUN: %clang_cc1 -E -dM -triple=armv7a-unknown-linux-gnueabihf /dev/null | FileCheck -match-full-lines -check-prefix TIME32 %s
// RUN: %clang_cc1 -E -dM -triple=armv7a-unknown-linux-gnueabihft64 /dev/null | FileCheck -match-full-lines -check-prefix TIME64 %s
//
// TIME32-NOT:#define _FILE_OFFSET_BITS 64
// TIME32-NOT:#define _TIME_BITS 64
//
// TIME64:#define _FILE_OFFSET_BITS 64
// TIME64:#define _TIME_BITS 64
2 changes: 1 addition & 1 deletion clang/test/Sema/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void test9(short v) {

old = __sync_fetch_and_add(); // expected-error {{too few arguments to function call}}
old = __sync_fetch_and_add(&old); // expected-error {{too few arguments to function call}}
old = __sync_fetch_and_add((unsigned*)0, 42i); // expected-warning {{imaginary constants are a GNU extension}}
old = __sync_fetch_and_add((unsigned*)0, 42i); // expected-warning {{imaginary constants are a C2y extension}}

// PR7600: Pointers are implicitly casted to integers and back.
void *old_ptr = __sync_val_compare_and_swap((void**)0, 0, 0);
Expand Down
69 changes: 69 additions & 0 deletions clang/test/Sema/constant-builtins-fmaximum-num.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
// FIXME: %clang_cc1 -std=c++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
// expected-no-diagnostics

constexpr double NaN = __builtin_nan("");
constexpr double SNaN = __builtin_nans("");
constexpr double Inf = __builtin_inf();
constexpr double NegInf = -__builtin_inf();

#define FMAXIMUMNUM_TEST_SIMPLE(T, FUNC) \
static_assert(T(6.7890) == FUNC(T(1.2345), T(6.7890))); \
static_assert(T(6.7890) == FUNC(T(6.7890), T(1.2345)));

#define FMAXIMUMNUM_TEST_SNAN(T, FUNC) \
static_assert(Inf == FUNC(SNaN, Inf)); \
static_assert(NegInf == FUNC(NegInf, SNaN)); \
static_assert(0.0 == FUNC(SNaN, 0.0)); \
static_assert(-0.0 == FUNC(-0.0, SNaN)); \
static_assert(T(-1.2345) == FUNC(SNaN, T(-1.2345))); \
static_assert(T(1.2345) == FUNC(T(1.2345), SNaN)); \
static_assert(__builtin_isnan(FUNC(SNaN, SNaN))); \
static_assert(__builtin_isnan(FUNC(NaN, SNaN))); \
static_assert(!__builtin_issignaling(FUNC(SNaN, SNaN))); \
static_assert(!__builtin_issignaling(FUNC(NaN, SNaN)));

#define FMAXIMUMNUM_TEST_NAN(T, FUNC) \
static_assert(Inf == FUNC(NaN, Inf)); \
static_assert(NegInf == FUNC(NegInf, NaN)); \
static_assert(0.0 == FUNC(NaN, 0.0)); \
static_assert(-0.0 == FUNC(-0.0, NaN)); \
static_assert(T(-1.2345) == FUNC(NaN, T(-1.2345))); \
static_assert(T(1.2345) == FUNC(T(1.2345), NaN)); \
static_assert(__builtin_isnan(FUNC(NaN, NaN)));

#define FMAXIMUMNUM_TEST_INF(T, FUNC) \
static_assert(Inf == FUNC(NegInf, Inf)); \
static_assert(Inf == FUNC(Inf, 0.0)); \
static_assert(Inf == FUNC(-0.0, Inf)); \
static_assert(Inf == FUNC(Inf, T(1.2345))); \
static_assert(Inf == FUNC(T(-1.2345), Inf));

#define FMAXIMUMNUM_TEST_NEG_INF(T, FUNC) \
static_assert(Inf == FUNC(Inf, NegInf)); \
static_assert(0.0 == FUNC(NegInf, 0.0)); \
static_assert(-0.0 == FUNC(-0.0, NegInf)); \
static_assert(T(-1.2345) == FUNC(NegInf, T(-1.2345))); \
static_assert(T(1.2345) == FUNC(T(1.2345), NegInf));

#define FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC) \
static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0); \
static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == 1.0); \
static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == 1.0); \
static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);

#define LIST_FMAXIMUMNUM_TESTS(T, FUNC) \
FMAXIMUMNUM_TEST_SIMPLE(T, FUNC) \
FMAXIMUMNUM_TEST_NAN(T, FUNC) \
FMAXIMUMNUM_TEST_SNAN(T, FUNC) \
FMAXIMUMNUM_TEST_INF(T, FUNC) \
FMAXIMUMNUM_TEST_NEG_INF(T, FUNC) \
FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)

LIST_FMAXIMUMNUM_TESTS(double, __builtin_fmaximum_num)
LIST_FMAXIMUMNUM_TESTS(float, __builtin_fmaximum_numf)
LIST_FMAXIMUMNUM_TESTS((long double), __builtin_fmaximum_numl)
LIST_FMAXIMUMNUM_TESTS(__fp16, __builtin_fmaximum_numf16)
#ifdef __FLOAT128__
LIST_FMAXIMUMNUM_TESTS(__float128, __builtin_fmaximum_numf128)
#endif
69 changes: 69 additions & 0 deletions clang/test/Sema/constant-builtins-fminimum-num.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
// FIXME: %clang_cc1 -std=c++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
// expected-no-diagnostics

constexpr double NaN = __builtin_nan("");
constexpr double SNaN = __builtin_nans("");
constexpr double Inf = __builtin_inf();
constexpr double NegInf = -__builtin_inf();

#define FMINIMUMNUM_TEST_SIMPLE(T, FUNC) \
static_assert(T(1.2345) == FUNC(T(1.2345), T(6.7890))); \
static_assert(T(1.2345) == FUNC(T(6.7890), T(1.2345)));

#define FMINIMUMNUM_TEST_NAN(T, FUNC) \
static_assert(Inf == FUNC(NaN, Inf)); \
static_assert(NegInf == FUNC(NegInf, NaN)); \
static_assert(0.0 == FUNC(NaN, 0.0)); \
static_assert(-0.0 == FUNC(-0.0, NaN)); \
static_assert(T(-1.2345) == FUNC(NaN, T(-1.2345))); \
static_assert(T(1.2345) == FUNC(T(1.2345), NaN)); \
static_assert(__builtin_isnan(FUNC(NaN, NaN)));

#define FMINIMUMNUM_TEST_SNAN(T, FUNC) \
static_assert(Inf == FUNC(SNaN, Inf)); \
static_assert(NegInf == FUNC(NegInf, SNaN)); \
static_assert(0.0 == FUNC(SNaN, 0.0)); \
static_assert(-0.0 == FUNC(-0.0, SNaN)); \
static_assert(T(-1.2345) == FUNC(SNaN, T(-1.2345))); \
static_assert(T(1.2345) == FUNC(T(1.2345), SNaN)); \
static_assert(__builtin_isnan(FUNC(SNaN, SNaN))); \
static_assert(__builtin_isnan(FUNC(NaN, SNaN))); \
static_assert(!__builtin_issignaling(FUNC(SNaN, SNaN))); \
static_assert(!__builtin_issignaling(FUNC(NaN, SNaN)));

#define FMINIMUMNUM_TEST_INF(T, FUNC) \
static_assert(NegInf == FUNC(NegInf, Inf)); \
static_assert(0.0 == FUNC(Inf, 0.0)); \
static_assert(-0.0 == FUNC(-0.0, Inf)); \
static_assert(T(1.2345) == FUNC(Inf, T(1.2345))); \
static_assert(T(-1.2345) == FUNC(T(-1.2345), Inf));

#define FMINIMUMNUM_TEST_NEG_INF(T, FUNC) \
static_assert(NegInf == FUNC(Inf, NegInf)); \
static_assert(NegInf == FUNC(NegInf, 0.0)); \
static_assert(NegInf == FUNC(-0.0, NegInf)); \
static_assert(NegInf == FUNC(NegInf, T(-1.2345))); \
static_assert(NegInf == FUNC(T(1.2345), NegInf));

#define FMINIMUMNUM_TEST_BOTH_ZERO(T, FUNC) \
static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0); \
static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == -1.0); \
static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == -1.0); \
static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);

#define LIST_FMINIMUMNUM_TESTS(T, FUNC) \
FMINIMUMNUM_TEST_SIMPLE(T, FUNC) \
FMINIMUMNUM_TEST_NAN(T, FUNC) \
FMINIMUMNUM_TEST_SNAN(T, FUNC) \
FMINIMUMNUM_TEST_INF(T, FUNC) \
FMINIMUMNUM_TEST_NEG_INF(T, FUNC) \
FMINIMUMNUM_TEST_BOTH_ZERO(T, FUNC)

LIST_FMINIMUMNUM_TESTS(double, __builtin_fminimum_num)
LIST_FMINIMUMNUM_TESTS(float, __builtin_fminimum_numf)
LIST_FMINIMUMNUM_TESTS((long double), __builtin_fminimum_numl)
LIST_FMINIMUMNUM_TESTS(__fp16, __builtin_fminimum_numf16)
#ifdef __FLOAT128__
LIST_FMINIMUMNUM_TESTS(__float128, __builtin_fminimum_numf128)
#endif
8 changes: 4 additions & 4 deletions clang/test/Sema/exprs.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ _Complex double test1(void) {
}

_Complex double test2(void) {
return 1.0if; // expected-warning {{imaginary constants are a GNU extension}}
return 1.0if; // expected-warning {{imaginary constants are a C2y extension}}
}

void test3(void) {
Expand All @@ -57,7 +57,7 @@ void test4(void) {

var =+5; // no warning when the subexpr of the unary op has no space before it.
var =-5;

#define FIVE 5
var=-FIVE; // no warning with macros.
var=-FIVE;
Expand Down Expand Up @@ -152,7 +152,7 @@ void test17(int x) {
x = x % 0; // expected-warning {{remainder by zero is undefined}}
x /= 0; // expected-warning {{division by zero is undefined}}
x %= 0; // expected-warning {{remainder by zero is undefined}}

x = sizeof(x/0); // no warning.
}

Expand Down Expand Up @@ -205,7 +205,7 @@ int test20(int x) {
// expected-note {{remove constant to silence this warning}}

return x && sizeof(int) == 4; // no warning, RHS is logical op.

// no warning, this is an idiom for "true" in old C style.
return x && (signed char)1;

Expand Down
3 changes: 3 additions & 0 deletions clang/test/SemaCXX/block-packs.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -fsyntax-only -verify -Wno-unused %s
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -fsyntax-only -verify -Wno-unused %s -frecovery-ast -frecovery-ast-type

// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -fsyntax-only -verify -Wno-unused -fexperimental-new-constant-interpreter %s
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -fsyntax-only -verify -Wno-unused -frecovery-ast -frecovery-ast-type -fexperimental-new-constant-interpreter %s

template <typename ...Ts>
void f() {
((^ { Ts t; }), ...);
Expand Down
34 changes: 29 additions & 5 deletions clang/test/SemaCXX/cxx2b-deducing-this.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ struct Corresponding {
void d(this Corresponding&&);
void d(this const Corresponding&);
void d(this const int&);
void d(this const int);
void d(this int);
void d(this const int); // expected-note {{previous declaration is here}}
void d(this int); // expected-error {{class member cannot be redeclared}}

void e(this const Corresponding&&); // expected-note {{here}}
void e() const &&; // expected-error{{cannot be redeclared}}
Expand Down Expand Up @@ -171,9 +171,8 @@ struct CorrespondingTpl {
void d(this Corresponding&&);
void d(this const Corresponding&);
void d(this const int&);
void d(this const int);
void d(this int);

void d(this const int); // expected-note {{previous declaration is here}}
void d(this int); // expected-error {{class member cannot be redeclared}}
void e(this const CorrespondingTpl&&); // expected-note {{here}}
void e() const &&; // expected-error{{cannot be redeclared}}
};
Expand Down Expand Up @@ -1073,3 +1072,28 @@ int main() {
return foo[]; // expected-error {{no viable overloaded operator[] for type 'Foo'}}
}
}

namespace GH100394 {
struct C1 {
void f(this const C1);
void f() const; // ok
};

struct C2 {
void f(this const C2); // expected-note {{previous declaration is here}}
void f(this volatile C2); // expected-error {{class member cannot be redeclared}} \
// expected-warning {{volatile-qualified parameter type 'volatile C2' is deprecated}}
};

struct C3 {
void f(this volatile C3); // expected-note {{previous declaration is here}} \
// expected-warning {{volatile-qualified parameter type 'volatile C3' is deprecated}}
void f(this const C3); // expected-error {{class member cannot be redeclared}}
};

struct C4 {
void f(this const C4); // expected-note {{previous declaration is here}}
void f(this const volatile C4); // expected-error {{class member cannot be redeclared}} \
// expected-warning {{volatile-qualified parameter type 'const volatile C4' is deprecated}}
};
}
13 changes: 13 additions & 0 deletions clang/test/SemaObjCXX/attr-nonblocking-constraints.mm
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,17 @@ void nb4() [[clang::nonblocking]] {
}
@catch (...) { // expected-warning {{function with 'nonblocking' attribute must not throw or catch exceptions}}
}
@finally { // expected-warning {{function with 'nonblocking' attribute must not throw or catch exceptions}}
}
}

@class Lock;
extern Lock *someLock;

void nb5() [[clang::nonblocking]] {
@autoreleasepool { // expected-warning {{function with 'nonblocking' attribute must not access ObjC methods or properties}}
}

@synchronized(someLock) { // expected-warning {{function with 'nonblocking' attribute must not access ObjC methods or properties}}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ void uses() {
// expected-error@+1{{OpenACC 'auto' clause is not valid on 'kernels' directive}}
#pragma acc kernels device_type(*) auto
while(1);
// expected-error@+2{{OpenACC clause 'worker' may not follow a 'device_type' clause in a compute construct}}
// expected-note@+1{{previous clause is here}}
// expected-error@+1{{OpenACC 'worker' clause is not valid on 'kernels' directive}}
#pragma acc kernels device_type(*) worker
while(1);
// expected-error@+2{{OpenACC clause 'nohost' may not follow a 'device_type' clause in a compute construct}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ void uses() {
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
#pragma acc loop auto if_present
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
#pragma acc loop auto worker
for(;;);
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
Expand Down Expand Up @@ -180,7 +179,6 @@ void uses() {
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
#pragma acc loop if_present auto
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
#pragma acc loop worker auto
for(;;);
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
Expand Down Expand Up @@ -318,7 +316,6 @@ void uses() {
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
#pragma acc loop independent if_present
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
#pragma acc loop independent worker
for(;;);
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
Expand Down Expand Up @@ -455,7 +452,6 @@ void uses() {
// expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}}
#pragma acc loop if_present independent
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
#pragma acc loop worker independent
for(;;);
// expected-warning@+1{{OpenACC clause 'vector' not yet implemented}}
Expand Down Expand Up @@ -591,9 +587,8 @@ void uses() {
// expected-note@+1{{previous clause is here}}
#pragma acc loop seq gang
for(;;);
// expected-error@+3{{OpenACC clause 'worker' may not appear on the same construct as a 'seq' clause on a 'loop' construct}}
// expected-note@+2{{previous clause is here}}
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
// expected-error@+2{{OpenACC clause 'worker' may not appear on the same construct as a 'seq' clause on a 'loop' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc loop seq worker
for(;;);
// expected-error@+3{{OpenACC clause 'vector' may not appear on the same construct as a 'seq' clause on a 'loop' construct}}
Expand Down Expand Up @@ -734,10 +729,8 @@ void uses() {
// expected-note@+1{{previous clause is here}}
#pragma acc loop gang seq
for(;;);
// TODO OpenACC: when 'worker' is implemented and makes it to the AST, this should diagnose because of a conflict with 'seq'.
// TODOexpected-error@+3{{OpenACC clause 'worker' may not appear on the same construct as a 'seq' clause on a 'loop' construct}}
// TODOexpected-note@+2{{previous clause is here}}
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented}}
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'worker' clause on a 'loop' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc loop worker seq
for(;;);
// TODO OpenACC: when 'vector' is implemented and makes it to the AST, this should diagnose because of a conflict with 'seq'.
Expand Down
1 change: 0 additions & 1 deletion clang/test/SemaOpenACC/loop-construct-device_type-clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ void uses() {
for(;;);
#pragma acc loop device_type(*) auto
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
#pragma acc loop device_type(*) worker
for(;;);
// expected-error@+2{{OpenACC clause 'nohost' may not follow a 'device_type' clause in a 'loop' construct}}
Expand Down
270 changes: 270 additions & 0 deletions clang/test/SemaOpenACC/loop-construct-worker-ast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s

// Test this with PCH.
// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
#ifndef PCH_HELPER
#define PCH_HELPER

template<unsigned I, typename ConvertsToInt, typename Int>
void TemplUses(ConvertsToInt CTI, Int IsI) {
// CHECK: FunctionTemplateDecl{{.*}}TemplUses
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'unsigned int' depth 0 index 0 I
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 ConvertsToInt
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 Int
// CHECK-NEXT: FunctionDecl{{.*}}TemplUses 'void (ConvertsToInt, Int)'
// CHECK-NEXT: ParmVarDecl{{.*}}CTI 'ConvertsToInt'
// CHECK-NEXT: ParmVarDecl{{.*}}IsI 'Int'
// CHECK-NEXT: CompoundStmt

// CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan>
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc loop worker
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc parallel
#pragma acc loop worker
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} serial
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc serial
#pragma acc loop worker
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: DeclRefExpr{{.*}} 'ConvertsToInt' lvalue ParmVar
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc kernels
#pragma acc loop worker(CTI)
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: DeclRefExpr{{.*}} 'Int' lvalue ParmVar
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc kernels
#pragma acc loop worker(num:IsI)
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: DeclRefExpr{{.*}} 'unsigned int' NonTypeTemplateParm{{.*}}'I' 'unsigned int'
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc kernels
#pragma acc loop worker(num:I)
for(;;);

// Instantiations:
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (Converts, int)' implicit_instantiation
// CHECK-NEXT: TemplateArgument integral '3U'
// CHECK-NEXT: TemplateArgument type 'Converts'
// CHECK-NEXT: RecordType{{.*}}'Converts'
// CHECK-NEXT: CXXRecord{{.*}}'Converts
// CHECK-NEXT: TemplateArgument type 'int'
// CHECK-NEXT: BuiltinType{{.*}}'int'
// CHECK-NEXT: ParmVarDecl{{.*}} CTI 'Converts'
// CHECK-NEXT: ParmVarDecl{{.*}} IsI 'int'
// CHECK-NEXT: CompoundStmt
//
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan>
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
//
// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
//
// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} serial
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
//
// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <UserDefinedConversion>
// CHECK-NEXT: CXXMemberCallExpr{{.*}} 'int'
// CHECK-NEXT: MemberExpr{{.*}} .operator int
// CHECK-NEXT: DeclRefExpr{{.*}} 'Converts' lvalue ParmVar
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
//
// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'IsI' 'int'
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
//
// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'unsigned int'
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}}'unsigned int' depth 0 index 0 I
// CHECK-NEXT: IntegerLiteral{{.*}} 'unsigned int' 3
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
}

struct Converts{
operator int();
};

void uses() {
// CHECK: FunctionDecl{{.*}} uses
// CHECK-NEXT: CompoundStmt
//
// CHECK-NEXT: CallExpr
TemplUses<3>(Converts{}, 5);

// CHECK: OpenACCLoopConstruct{{.*}}<orphan>
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc loop worker
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc parallel
#pragma acc loop worker
for(;;);

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} serial
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc serial
#pragma acc loop worker
for(;;);

Converts CTI;
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl
// CHECK-NEXT: CXXConstructExpr

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <UserDefinedConversion>
// CHECK-NEXT: CXXMemberCallExpr{{.*}} 'int'
// CHECK-NEXT: MemberExpr{{.*}} .operator int
// CHECK-NEXT: DeclRefExpr{{.*}}'Converts' lvalue Var
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc kernels
#pragma acc loop worker(CTI)
for(;;);

int IsI;
// CHECK-NEXT: DeclStmt
// CHECK-NEXT: VarDecl

// CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels
// CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]]
// CHECK-NEXT: worker clause{{.*}}
// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: NullStmt
#pragma acc kernels
#pragma acc loop worker(num:IsI)
for(;;);
}

#endif // PCH_HELPER
202 changes: 202 additions & 0 deletions clang/test/SemaOpenACC/loop-construct-worker-clause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// RUN: %clang_cc1 %s -fopenacc -verify

template<unsigned I, typename NotInt, typename ConvertsToInt, typename Int>
void TemplUses(NotInt NI, ConvertsToInt CTI, Int IsI) {
int i;

// expected-error@+1{{'num' argument on 'worker' clause is not permitted on an orphaned 'loop' construct}}
#pragma acc loop worker(i)
for(;;);

// expected-error@+1{{'num' argument on 'worker' clause is not permitted on an orphaned 'loop' construct}}
#pragma acc loop worker(num:IsI)
for(;;);

#pragma acc kernels
#pragma acc loop worker
for(;;);

#pragma acc kernels
#pragma acc loop worker(i)
for(;;);

#pragma acc kernels
#pragma acc loop worker(CTI)
for(;;);

#pragma acc kernels
#pragma acc loop worker(IsI)
for(;;);

#pragma acc kernels
#pragma acc loop worker(I)
for(;;);

#pragma acc kernels
// expected-error@+1{{OpenACC clause 'worker' requires expression of integer type ('NoConvert' invalid)}}
#pragma acc loop worker(NI)
for(;;);

#pragma acc kernels
#pragma acc loop worker(num:i)
for(;;);

// expected-error@+3{{'num' argument to 'worker' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'num_workers' clause}}
// expected-note@+1{{previous clause is here}}
#pragma acc kernels num_workers(IsI)
#pragma acc loop worker(num:CTI)
for(;;);
for(;;);
}

struct NoConvert{};
struct Converts{
operator int();
};

void uses() {
TemplUses<3>(NoConvert{}, Converts{}, 5); // expected-note{{in instantiation of function template specialization}}

#pragma acc loop worker
for(;;);

#pragma acc parallel
#pragma acc loop worker
for(;;);

int i;

// expected-error@+1{{'num' argument on 'worker' clause is not permitted on an orphaned 'loop' construct}}
#pragma acc loop worker(i)
for(;;);

// expected-error@+2{{'num' argument on 'worker' clause is not permitted on a 'loop' construct associated with a 'parallel' compute construct}}
#pragma acc parallel
#pragma acc loop worker(i)
for(;;);

// expected-error@+1{{'num' argument on 'worker' clause is not permitted on an orphaned 'loop' construct}}
#pragma acc loop worker(num:i)
for(;;);

// expected-error@+2{{'num' argument on 'worker' clause is not permitted on a 'loop' construct associated with a 'parallel' compute construct}}
#pragma acc parallel
#pragma acc loop worker(num:i)
for(;;);

#pragma acc serial
#pragma acc loop worker
for(;;);

// expected-error@+2{{'num' argument on 'worker' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
#pragma acc serial
#pragma acc loop worker(i)
for(;;);

// expected-error@+2{{'num' argument on 'worker' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
#pragma acc serial
#pragma acc loop worker(num:i)
for(;;);

#pragma acc kernels
#pragma acc loop worker
for(;;);

#pragma acc kernels
#pragma acc loop worker(i)
for(;;);

Converts Cvts;

#pragma acc kernels
#pragma acc loop worker(Cvts)
for(;;);

NoConvert NoCvts;

#pragma acc kernels
// expected-error@+1{{OpenACC clause 'worker' requires expression of integer type ('NoConvert' invalid)}}
#pragma acc loop worker(NoCvts)
for(;;);

#pragma acc kernels
#pragma acc loop worker(num:i)
for(;;);

// expected-error@+3{{'num' argument to 'worker' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'num_workers' clause}}
// expected-note@+1{{previous clause is here}}
#pragma acc kernels num_workers(i)
#pragma acc loop worker(num:i)
for(;;);

#pragma acc loop worker
for(;;) {
// expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}}
// expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}}
// expected-note@-4 2{{previous clause is here}}
#pragma acc loop worker, gang
for(;;) {}
}

#pragma acc loop worker
for(;;) {
#pragma acc parallel
#pragma acc loop worker, gang
for(;;) {}
}


#pragma acc parallel
#pragma acc loop worker
for(;;) {
// expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}}
// expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}}
// expected-note@-4 2{{previous clause is here}}
#pragma acc loop worker, gang
for(;;) {}
}

#pragma acc parallel
#pragma acc loop worker
for(;;) {
#pragma acc parallel
#pragma acc loop worker, gang
for(;;) {}
}

#pragma acc serial
#pragma acc loop worker
for(;;) {
// expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}}
// expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}}
// expected-note@-4 2{{previous clause is here}}
#pragma acc loop worker, gang
for(;;) {}
}

#pragma acc serial
#pragma acc loop worker
for(;;) {
#pragma acc parallel
#pragma acc loop worker, gang
for(;;) {}
}

#pragma acc kernels
#pragma acc loop worker
for(;;) {
// expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}}
// expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}}
// expected-note@-4 2{{previous clause is here}}
#pragma acc loop worker, gang
for(;;) {}
}

#pragma acc kernels
#pragma acc loop worker
for(;;) {
#pragma acc parallel
#pragma acc loop worker, gang
for(;;) {}
}
}
5 changes: 5 additions & 0 deletions clang/tools/libclang/CIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2888,6 +2888,11 @@ void OpenACCClauseEnqueue::VisitAsyncClause(const OpenACCAsyncClause &C) {
if (C.hasIntExpr())
Visitor.AddStmt(C.getIntExpr());
}

void OpenACCClauseEnqueue::VisitWorkerClause(const OpenACCWorkerClause &C) {
if (C.hasIntExpr())
Visitor.AddStmt(C.getIntExpr());
}
void OpenACCClauseEnqueue::VisitWaitClause(const OpenACCWaitClause &C) {
if (const Expr *DevNumExpr = C.getDevNumExpr())
Visitor.AddStmt(DevNumExpr);
Expand Down
4 changes: 4 additions & 0 deletions clang/tools/libclang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ if(ENABLE_SHARED)
PROPERTIES
VERSION ${LIBCLANG_LIBRARY_VERSION}
DEFINE_SYMBOL _CINDEX_LIB_)
# Avoid declaring clang c++ symbols that are statically linked into libclang as dllimport'ed.
# If llvm/libclang-cpp dll is also being built for windows clang c++ symbols will still be
# implicitly be exported from libclang.
target_compile_definitions(libclang PRIVATE CLANG_BUILD_STATIC)
elseif(APPLE)
set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
set(LIBCLANG_LINK_FLAGS "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
Expand Down
11 changes: 10 additions & 1 deletion clang/unittests/Format/ConfigParseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
CHECK_PARSE_BOOL(ReflowComments);
CHECK_PARSE_BOOL(RemoveBracesLLVM);
CHECK_PARSE_BOOL(RemoveSemicolon);
CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
Expand Down Expand Up @@ -381,6 +380,16 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment,
FormatStyle::PAS_Middle);

Style.ReflowComments = FormatStyle::RCS_Always;
CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never);
CHECK_PARSE("ReflowComments: IndentOnly", ReflowComments,
FormatStyle::RCS_IndentOnly);
CHECK_PARSE("ReflowComments: Always", ReflowComments,
FormatStyle::RCS_Always);
// For backward compatibility:
CHECK_PARSE("ReflowComments: false", ReflowComments, FormatStyle::RCS_Never);
CHECK_PARSE("ReflowComments: true", ReflowComments, FormatStyle::RCS_Always);

Style.Standard = FormatStyle::LS_Auto;
CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03);
CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11);
Expand Down
6 changes: 3 additions & 3 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18108,7 +18108,7 @@ TEST_F(FormatTest, AlignConsecutiveMacros) {

// Test across comments
Style.MaxEmptyLinesToKeep = 10;
Style.ReflowComments = false;
Style.ReflowComments = FormatStyle::RCS_Never;
Style.AlignConsecutiveMacros.AcrossComments = true;
verifyFormat("#define a 3\n"
"// line comment\n"
Expand Down Expand Up @@ -18855,7 +18855,7 @@ TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLinesAndComments) {
"y = 1;",
Alignment);

Alignment.ReflowComments = true;
Alignment.ReflowComments = FormatStyle::RCS_Always;
Alignment.ColumnLimit = 50;
verifyFormat("int x = 0;\n"
"int yy = 1; /// specificlennospace\n"
Expand Down Expand Up @@ -19253,7 +19253,7 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
"y = 1;",
Alignment);

EXPECT_EQ(Alignment.ReflowComments, true);
EXPECT_EQ(Alignment.ReflowComments, FormatStyle::RCS_Always);
Alignment.ColumnLimit = 50;
verifyFormat("int x = 0;\n"
"int yy = 1; /// specificlennospace\n"
Expand Down
29 changes: 28 additions & 1 deletion clang/unittests/Format/FormatTestComments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,36 @@ TEST_F(FormatTestComments, AlignsBlockComments) {

TEST_F(FormatTestComments, CommentReflowingCanBeTurnedOff) {
FormatStyle Style = getLLVMStyleWithColumns(20);
Style.ReflowComments = false;
Style.ReflowComments = FormatStyle::RCS_Never;
verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style);
verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style);
verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
"aaaaaaaaa*/",
Style);
verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
" aaaaaaaaa*/",
Style);
verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
" * aaaaaaaaa*/",
Style);
}

TEST_F(FormatTestComments, CommentReflowingCanApplyOnlyToIndents) {
FormatStyle Style = getLLVMStyleWithColumns(20);
Style.ReflowComments = FormatStyle::RCS_IndentOnly;
verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style);
verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style);
verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
"aaaaaaaaa*/",
Style);
verifyNoChange("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
" aaaaaaaaa*/",
Style);
verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
" * aaaaaaaaa*/",
"/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa\n"
" * aaaaaaaaa*/",
Style);
}

TEST_F(FormatTestComments, CorrectlyHandlesLengthOfBlockComments) {
Expand Down
1 change: 1 addition & 0 deletions clang/unittests/Format/FormatTestVerilog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ TEST_F(FormatTestVerilog, Instantiation) {
" .qbar(out1),\n"
" .clear(in1),\n"
" .preset(in2));");
verifyNoCrash(", ff1();");
// With breaking between instance ports disabled.
auto Style = getDefaultStyle();
Style.VerilogBreakBetweenInstancePorts = false;
Expand Down
2 changes: 1 addition & 1 deletion clang/www/c_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ <h2 id="c2y">C2y implementation status</h2>
<tr>
<td>Introduce complex literals v. 2</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3298.htm">N3298</a></td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Yes</td>
</tr>
<tr>
<td>Allow zero length operations on null pointers</td>
Expand Down
5 changes: 5 additions & 0 deletions compiler-rt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ endif()
include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake
NO_POLICY_SCOPE)

# TODO(CMake 3.22): remove
if(POLICY CMP0128)
cmake_policy(SET CMP0128 NEW)
endif()

# Check if compiler-rt is built as a standalone project.
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR COMPILER_RT_STANDALONE_BUILD)
project(CompilerRT C CXX ASM)
Expand Down
9 changes: 7 additions & 2 deletions compiler-rt/cmake/Modules/AddCompilerRT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ endmacro()
# LINK_LIBS <linked libraries> (only for shared library)
# OBJECT_LIBS <object libraries to use as sources>
# PARENT_TARGET <convenience parent target>
# ADDITIONAL_HEADERS <header files>)
# ADDITIONAL_HEADERS <header files>
# EXTENSIONS <boolean>)
function(add_compiler_rt_runtime name type)
if(NOT type MATCHES "^(OBJECT|STATIC|SHARED|MODULE)$")
message(FATAL_ERROR
Expand All @@ -171,7 +172,7 @@ function(add_compiler_rt_runtime name type)
cmake_parse_arguments(LIB
""
"PARENT_TARGET"
"OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;DEPS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS"
"OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;DEPS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS;EXTENSIONS"
${ARGN})
set(libnames)
# Until we support this some other way, build compiler-rt runtime without LTO
Expand Down Expand Up @@ -435,6 +436,10 @@ function(add_compiler_rt_runtime name type)
if(type STREQUAL "SHARED")
rt_externalize_debuginfo(${libname})
endif()

if(DEFINED LIB_EXTENSIONS)
set_target_properties(${libname} PROPERTIES C_EXTENSIONS ${LIB_EXTENSIONS})
endif()
endforeach()
if(LIB_PARENT_TARGET)
add_dependencies(${LIB_PARENT_TARGET} ${libnames})
Expand Down
3 changes: 1 addition & 2 deletions compiler-rt/lib/asan/asan_fuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
// In lieu of AsanThread::Create.
AsanThread *thread = (AsanThread *)MmapOrDie(AsanThreadMmapSize(), __func__);

AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
u32 tid = asanThreadRegistry().CreateThread(0, detached, parent_tid, &args);
u32 tid = asanThreadRegistry().CreateThread(0, detached, parent_tid, thread);
asanThreadRegistry().SetThreadName(tid, name);

return thread;
Expand Down
16 changes: 10 additions & 6 deletions compiler-rt/lib/asan/asan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,15 @@
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_thread_history.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"

namespace __asan {

// AsanThreadContext implementation.

void AsanThreadContext::OnCreated(void *arg) {
CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs *>(arg);
if (args->stack)
stack_id = StackDepotPut(*args->stack);
thread = args->thread;
thread = static_cast<AsanThread *>(arg);
thread->set_context(this);
}

Expand Down Expand Up @@ -106,8 +104,8 @@ AsanThread *AsanThread::Create(const void *start_data, uptr data_size,
CHECK_LE(data_size, availible_size);
internal_memcpy(thread->start_data_, start_data, data_size);
}
AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
asanThreadRegistry().CreateThread(0, detached, parent_tid, &args);
asanThreadRegistry().CreateThread(0, detached, parent_tid,
stack ? StackDepotPut(*stack) : 0, thread);

return thread;
}
Expand Down Expand Up @@ -558,6 +556,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
threads);
}

void PrintThreads() {
InternalScopedString out;
PrintThreadHistory(__asan::asanThreadRegistry(), out);
Report("%s\n", out.data());
}

} // namespace __lsan

// ---------------------- Interface ---------------- {{{1
Expand Down
11 changes: 3 additions & 8 deletions compiler-rt/lib/asan/asan_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,16 @@ class AsanThread;
class AsanThreadContext final : public ThreadContextBase {
public:
explicit AsanThreadContext(int tid)
: ThreadContextBase(tid), announced(false),
destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
: ThreadContextBase(tid),
announced(false),
destructor_iterations(GetPthreadDestructorIterations()),
thread(nullptr) {}
bool announced;
u8 destructor_iterations;
u32 stack_id;
AsanThread *thread;

void OnCreated(void *arg) override;
void OnFinished() override;

struct CreateThreadContextArgs {
AsanThread *thread;
StackTrace *stack;
};
};

// AsanThreadContext objects are never freed, so we need many of them.
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/builtins/cpu_model/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ struct {

struct {
unsigned mvendorid;
unsigned marchid;
unsigned mimpid;
unsigned long long marchid;
unsigned long long mimpid;
} __riscv_cpu_model __attribute__((visibility("hidden"), nocommon));

// NOTE: Should sync-up with RISCVFeatures.td
Expand Down
7 changes: 6 additions & 1 deletion compiler-rt/lib/hwasan/hwasan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
__hwasan::hwasanThreadArgRetval().GetAllPtrsLocked(ptrs);
}

void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {}
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
// TODO: implement.
}
void PrintThreads() {
// TODO: implement.
}

} // namespace __lsan
17 changes: 12 additions & 5 deletions compiler-rt/lib/lsan/lsan_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,14 +771,15 @@ static bool PrintResults(LeakReport &report) {
}
if (common_flags()->print_suppressions)
GetSuppressionContext()->PrintMatchedSuppressions();
if (unsuppressed_count > 0) {
if (unsuppressed_count)
report.PrintSummary();
return true;
}
return false;
if ((unsuppressed_count && common_flags()->verbosity >= 2) ||
flags()->log_threads)
PrintThreads();
return unsuppressed_count;
}

static bool CheckForLeaks() {
static bool CheckForLeaksOnce() {
if (&__lsan_is_turned_off && __lsan_is_turned_off()) {
VReport(1, "LeakSanitizer is disabled\n");
return false;
Expand Down Expand Up @@ -830,6 +831,12 @@ static bool CheckForLeaks() {
}
}

static bool CheckForLeaks() {
int leaking_tries = 0;
for (int i = 0; i < flags()->tries; ++i) leaking_tries += CheckForLeaksOnce();
return leaking_tries == flags()->tries;
}

static bool has_reported_leaks = false;
bool HasReportedLeaks() { return has_reported_leaks; }

Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/lsan/lsan_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ void GetThreadExtraStackRangesLocked(tid_t os_id,
InternalMmapVector<Range> *ranges);
void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs);
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
void PrintThreads();

//// --------------------------------------------------------------------------
//// Allocator prototypes.
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/lsan/lsan_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ LSAN_FLAG(bool, use_poisoned, false,
"Consider pointers found in poisoned memory to be valid.")
LSAN_FLAG(bool, log_pointers, false, "Debug logging")
LSAN_FLAG(bool, log_threads, false, "Debug logging")
LSAN_FLAG(int, tries, 1, "Debug option to repeat leak checking multiple times")
LSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
LSAN_FLAG(int, thread_suspend_fail, 1,
"Behaviour if thread suspendion all thread (0 - "
Expand Down
7 changes: 7 additions & 0 deletions compiler-rt/lib/lsan/lsan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "lsan_common.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_thread_history.h"
#include "sanitizer_common/sanitizer_thread_registry.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"

Expand Down Expand Up @@ -109,6 +110,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
threads);
}

void PrintThreads() {
InternalScopedString out;
PrintThreadHistory(*thread_registry, out);
Report("%s\n", out.data());
}

void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
GetThreadArgRetval().GetAllPtrsLocked(ptrs);
}
Expand Down
9 changes: 3 additions & 6 deletions compiler-rt/lib/memprof/memprof_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ namespace __memprof {
// MemprofThreadContext implementation.

void MemprofThreadContext::OnCreated(void *arg) {
CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs *>(arg);
if (args->stack)
stack_id = StackDepotPut(*args->stack);
thread = args->thread;
thread = static_cast<MemprofThread *>(arg);
thread->set_context(this);
}

Expand Down Expand Up @@ -79,8 +76,8 @@ MemprofThread *MemprofThread::Create(thread_callback_t start_routine, void *arg,
MemprofThread *thread = (MemprofThread *)MmapOrDie(size, __func__);
thread->start_routine_ = start_routine;
thread->arg_ = arg;
MemprofThreadContext::CreateThreadContextArgs args = {thread, stack};
memprofThreadRegistry().CreateThread(0, detached, parent_tid, &args);
memprofThreadRegistry().CreateThread(
0, detached, parent_tid, stack ? StackDepotPut(*stack) : 0, thread);

return thread;
}
Expand Down
8 changes: 1 addition & 7 deletions compiler-rt/lib/memprof/memprof_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,14 @@ class MemprofThread;
struct MemprofThreadContext final : public ThreadContextBase {
explicit MemprofThreadContext(int tid)
: ThreadContextBase(tid), announced(false),
destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
destructor_iterations(GetPthreadDestructorIterations()),
thread(nullptr) {}
bool announced;
u8 destructor_iterations;
u32 stack_id;
MemprofThread *thread;

void OnCreated(void *arg) override;
void OnFinished() override;

struct CreateThreadContextArgs {
MemprofThread *thread;
StackTrace *stack;
};
};

// MemprofThreadContext objects are never freed, so we need many of them.
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/lib/profile/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,15 @@ if(APPLE)
CFLAGS ${EXTRA_FLAGS}
SOURCES ${PROFILE_SOURCES}
ADDITIONAL_HEADERS ${PROFILE_HEADERS}
PARENT_TARGET profile)
PARENT_TARGET profile
EXTENSIONS ON)
else()
add_compiler_rt_runtime(clang_rt.profile
STATIC
ARCHS ${PROFILE_SUPPORTED_ARCH}
CFLAGS ${EXTRA_FLAGS}
SOURCES ${PROFILE_SOURCES}
ADDITIONAL_HEADERS ${PROFILE_HEADERS}
PARENT_TARGET profile)
PARENT_TARGET profile
EXTENSIONS ON)
endif()
3 changes: 3 additions & 0 deletions compiler-rt/lib/rtsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ set(RTSAN_CXX_SOURCES
rtsan_flags.cpp
rtsan_interceptors.cpp
rtsan_stats.cpp
rtsan_suppressions.cpp
)

set(RTSAN_PREINIT_SOURCES
rtsan_preinit.cpp)

set(RTSAN_HEADERS
rtsan.h
rtsan_checks.inc
rtsan_assertions.h
rtsan_context.h
rtsan_diagnostics.h
rtsan_flags.h
rtsan_flags.inc
rtsan_stats.h
rtsan_suppressions.h
)

set(RTSAN_DEPS)
Expand Down
4 changes: 3 additions & 1 deletion compiler-rt/lib/rtsan/rtsan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
#include "rtsan/rtsan_flags.h"
#include "rtsan/rtsan_interceptors.h"
#include "rtsan/rtsan_stats.h"
#include "rtsan/rtsan_suppressions.h"

#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_mutex.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_stacktrace.h"

using namespace __rtsan;
using namespace __sanitizer;
Expand Down Expand Up @@ -85,6 +85,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
InitializeFlags();
InitializeInterceptors();

InitializeSuppressions();

if (flags().print_stats_on_exit)
Atexit(PrintStatisticsSummary);

Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/rtsan/rtsan_assertions.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "rtsan/rtsan.h"
#include "rtsan/rtsan_context.h"
#include "rtsan/rtsan_diagnostics.h"
#include "rtsan/rtsan_suppressions.h"

#include "sanitizer_common/sanitizer_stacktrace.h"

Expand All @@ -34,6 +35,9 @@ void ExpectNotRealtime(Context &context, const DiagnosticsInfo &info,
stack.Unwind(info.pc, info.bp, nullptr,
__sanitizer::common_flags()->fast_unwind_on_fatal);

if (IsStackTraceSuppressed(stack))
return;

OnViolation(stack, info);
}
}
Expand Down
Loading