Skip to content

Commit b32a265

Browse files
erichkeaneakadutta
authored andcommitted
[OpenACC] Fix uses of getBaseOriginalType when we really want elt type. (llvm#162880)
Lately, I've been using 'getBaseOriginalType' in ArraySectionExpr incorrectly: it gets the base-ist of element type, when in reality, I want a single type of indirection. This patch corrects the handful of uses that I had for it.
1 parent e0ac54c commit b32a265

File tree

10 files changed

+162
-94
lines changed

10 files changed

+162
-94
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7160,6 +7160,18 @@ class ArraySectionExpr : public Expr {
71607160
/// Return original type of the base expression for array section.
71617161
static QualType getBaseOriginalType(const Expr *Base);
71627162

7163+
/// Return the effective 'element' type of this array section. As the array
7164+
/// section itself returns a collection of elements (closer to its `getBase`
7165+
/// type), this is only useful for figuring out the effective type of this if
7166+
/// it were a normal Array subscript expr.
7167+
QualType getElementType() const;
7168+
7169+
/// Returns the effective 'type' of the base of this array section. This
7170+
/// should be the array/pointer type that this operates on. Just
7171+
/// getBase->getType isn't sufficient, since it doesn't look through existing
7172+
/// Array sections to figure out the actual 'base' of this.
7173+
QualType getBaseType() const;
7174+
71637175
static bool classof(const Stmt *T) {
71647176
return T->getStmtClass() == ArraySectionExprClass;
71657177
}

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ class SemaOpenACC : public SemaBase {
911911
ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
912912
OpenACCReductionOperator ReductionOp,
913913
Expr *VarExpr);
914+
bool CheckReductionVarType(Expr *VarExpr);
914915

915916
/// Called to check the 'var' type is a variable of pointer type, necessary
916917
/// for 'deviceptr' and 'attach' clauses. Returns true on success.

clang/lib/AST/Expr.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5290,6 +5290,33 @@ QualType ArraySectionExpr::getBaseOriginalType(const Expr *Base) {
52905290
return OriginalTy;
52915291
}
52925292

5293+
QualType ArraySectionExpr::getElementType() const {
5294+
QualType BaseTy = getBase()->IgnoreParenImpCasts()->getType();
5295+
// We only have to look into the array section exprs, else we will get the
5296+
// type of the base, which should already be valid.
5297+
if (auto *ASE = dyn_cast<ArraySectionExpr>(getBase()->IgnoreParenImpCasts()))
5298+
BaseTy = ASE->getElementType();
5299+
5300+
if (BaseTy->isAnyPointerType())
5301+
return BaseTy->getPointeeType();
5302+
if (BaseTy->isArrayType())
5303+
return BaseTy->castAsArrayTypeUnsafe()->getElementType();
5304+
5305+
// If this isn't a pointer or array, the base is a dependent expression, so
5306+
// just return the BaseTy anyway.
5307+
assert(BaseTy->isInstantiationDependentType());
5308+
return BaseTy;
5309+
}
5310+
5311+
QualType ArraySectionExpr::getBaseType() const {
5312+
// We only have to look into the array section exprs, else we will get the
5313+
// type of the base, which should already be valid.
5314+
if (auto *ASE = dyn_cast<ArraySectionExpr>(getBase()->IgnoreParenImpCasts()))
5315+
return ASE->getElementType();
5316+
5317+
return getBase()->IgnoreParenImpCasts()->getType();
5318+
}
5319+
52935320
RecoveryExpr::RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc,
52945321
SourceLocation EndLoc, ArrayRef<Expr *> SubExprs)
52955322
: Expr(RecoveryExprClass, T.getNonReferenceType(),

clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {
7373
// Array sections are special, and we have to treat them that way.
7474
if (const auto *section =
7575
dyn_cast<ArraySectionExpr>(curVarExpr->IgnoreParenImpCasts()))
76-
origType = ArraySectionExpr::getBaseOriginalType(section);
76+
origType = section->getElementType();
7777

7878
mlir::Location exprLoc = cgm.getLoc(curVarExpr->getBeginLoc());
7979
llvm::SmallVector<mlir::Value> bounds;
@@ -84,16 +84,10 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {
8484
e->printPretty(os, nullptr, getContext().getPrintingPolicy());
8585

8686
auto addBoundType = [&](const Expr *e) {
87-
if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) {
88-
QualType baseTy = ArraySectionExpr::getBaseOriginalType(
89-
section->getBase()->IgnoreParenImpCasts());
90-
if (auto *at = getContext().getAsArrayType(baseTy))
91-
boundTypes.push_back(at->getElementType());
92-
else
93-
boundTypes.push_back(baseTy->getPointeeType());
94-
} else {
87+
if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr))
88+
boundTypes.push_back(section->getElementType());
89+
else
9590
boundTypes.push_back(curVarExpr->getType());
96-
}
9791
};
9892

9993
addBoundType(curVarExpr);
@@ -113,8 +107,7 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {
113107
if (const Expr *len = section->getLength()) {
114108
extent = emitOpenACCIntExpr(len);
115109
} else {
116-
QualType baseTy = ArraySectionExpr::getBaseOriginalType(
117-
section->getBase()->IgnoreParenImpCasts());
110+
QualType baseTy = section->getBaseType();
118111
// We know this is the case as implicit lengths are only allowed for
119112
// array types with a constant size, or a dependent size. AND since
120113
// we are codegen we know we're not dependent.

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,7 +2759,7 @@ OpenACCPrivateRecipe SemaOpenACC::CreatePrivateInitRecipe(const Expr *VarExpr) {
27592759
// Array sections are special, and we have to treat them that way.
27602760
if (const auto *ASE =
27612761
dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()))
2762-
VarTy = ArraySectionExpr::getBaseOriginalType(ASE);
2762+
VarTy = ASE->getElementType();
27632763

27642764
VarDecl *AllocaDecl = CreateAllocaDecl(
27652765
getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),
@@ -2795,7 +2795,7 @@ SemaOpenACC::CreateFirstPrivateInitRecipe(const Expr *VarExpr) {
27952795
// Array sections are special, and we have to treat them that way.
27962796
if (const auto *ASE =
27972797
dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()))
2798-
VarTy = ArraySectionExpr::getBaseOriginalType(ASE);
2798+
VarTy = ASE->getElementType();
27992799

28002800
VarDecl *AllocaDecl = CreateAllocaDecl(
28012801
getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),
@@ -2896,7 +2896,7 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe(
28962896
// Array sections are special, and we have to treat them that way.
28972897
if (const auto *ASE =
28982898
dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()))
2899-
VarTy = ArraySectionExpr::getBaseOriginalType(ASE);
2899+
VarTy = ASE->getElementType();
29002900

29012901
VarDecl *AllocaDecl = CreateAllocaDecl(
29022902
getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),

clang/lib/Sema/SemaOpenACCClause.cpp

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,51 +1915,34 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
19151915
return Result;
19161916
}
19171917

1918-
/// OpenACC 3.3 section 2.5.15:
1919-
/// At a mininmum, the supported data types include ... the numerical data types
1920-
/// in C, C++, and Fortran.
1921-
///
1922-
/// If the reduction var is a composite variable, each
1923-
/// member of the composite variable must be a supported datatype for the
1924-
/// reduction operation.
1925-
ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
1926-
OpenACCReductionOperator ReductionOp,
1927-
Expr *VarExpr) {
1928-
// For now, we only support 'scalar' types, or composites/arrays of scalar
1929-
// types.
1930-
VarExpr = VarExpr->IgnoreParenCasts();
1918+
bool SemaOpenACC::CheckReductionVarType(Expr *VarExpr) {
19311919
SourceLocation VarLoc = VarExpr->getBeginLoc();
19321920

19331921
SmallVector<PartialDiagnosticAt> Notes;
1934-
QualType CurType = VarExpr->getType();
1935-
1936-
// For array like things, the expression can either be an array element
1937-
// (subscript expr), array section, or array type. Peel those off, and add
1938-
// notes in case we find an illegal kind. We'll allow scalar or composite of
1939-
// scalars inside of this.
1940-
if (auto *ASE = dyn_cast<ArraySectionExpr>(VarExpr)) {
1941-
QualType BaseType = ArraySectionExpr::getBaseOriginalType(ASE);
1922+
// The standard isn't clear how many levels of 'array element' or 'subarray'
1923+
// are permitted, but we can handle as many as we need, so we'll strip them
1924+
// off here. This will result in CurType being the actual 'type' of the
1925+
// expression, which is what we are looking to check.
1926+
QualType CurType = isa<ArraySectionExpr>(VarExpr)
1927+
? ArraySectionExpr::getBaseOriginalType(VarExpr)
1928+
: VarExpr->getType();
1929+
1930+
// This can happen when we have a dependent type in an array element that the
1931+
// above function has tried to 'unwrap'. Since this can only happen with
1932+
// dependence, just let it go.
1933+
if (CurType.isNull())
1934+
return false;
19421935

1943-
PartialDiagnostic PD = PDiag(diag::note_acc_reduction_array)
1944-
<< diag::OACCReductionArray::Section << BaseType;
1945-
Notes.push_back({ASE->getBeginLoc(), PD});
1946-
1947-
CurType = getASTContext().getBaseElementType(BaseType);
1948-
} else if (auto *SubExpr = dyn_cast<ArraySubscriptExpr>(VarExpr)) {
1949-
// Array subscript already results in the type of the thing as its type, so
1950-
// there is no type to change here.
1951-
PartialDiagnostic PD =
1952-
PDiag(diag::note_acc_reduction_array)
1953-
<< diag::OACCReductionArray::Subscript
1954-
<< SubExpr->getBase()->IgnoreParenImpCasts()->getType();
1955-
Notes.push_back({SubExpr->getBeginLoc(), PD});
1956-
} else if (auto *AT = getASTContext().getAsArrayType(CurType)) {
1936+
// If we are still an array type, we allow 1 level of 'unpeeling' of the
1937+
// array. The standard isn't clear here whether this is allowed, but
1938+
// array-of-valid-things makes sense.
1939+
if (auto *AT = getASTContext().getAsArrayType(CurType)) {
19571940
// If we're already the array type, peel off the array and leave the element
19581941
// type.
1959-
CurType = getASTContext().getBaseElementType(AT);
19601942
PartialDiagnostic PD = PDiag(diag::note_acc_reduction_array)
19611943
<< diag::OACCReductionArray::ArrayTy << CurType;
19621944
Notes.push_back({VarLoc, PD});
1945+
CurType = AT->getElementType();
19631946
}
19641947

19651948
auto IsValidMemberOfComposite = [](QualType Ty) {
@@ -1974,31 +1957,26 @@ ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
19741957
for (auto [Loc, PD] : Notes)
19751958
Diag(Loc, PD);
19761959

1977-
Diag(VarLoc, diag::note_acc_reduction_type_summary);
1960+
return Diag(VarLoc, diag::note_acc_reduction_type_summary);
19781961
};
19791962

19801963
// If the type is already scalar, or is dependent, just give up.
19811964
if (IsValidMemberOfComposite(CurType)) {
19821965
// Nothing to do here, is valid.
19831966
} else if (auto *RD = CurType->getAsRecordDecl()) {
1984-
if (!RD->isStruct() && !RD->isClass()) {
1985-
EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1986-
<< RD << diag::OACCReductionTy::NotClassStruct);
1987-
return ExprError();
1988-
}
1967+
if (!RD->isStruct() && !RD->isClass())
1968+
return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1969+
<< RD
1970+
<< diag::OACCReductionTy::NotClassStruct);
19891971

1990-
if (!RD->isCompleteDefinition()) {
1991-
EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1992-
<< RD << diag::OACCReductionTy::NotComplete);
1993-
return ExprError();
1994-
}
1972+
if (!RD->isCompleteDefinition())
1973+
return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1974+
<< RD << diag::OACCReductionTy::NotComplete);
19951975

19961976
if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1997-
CXXRD && !CXXRD->isAggregate()) {
1998-
EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1999-
<< CXXRD << diag::OACCReductionTy::NotAgg);
2000-
return ExprError();
2001-
}
1977+
CXXRD && !CXXRD->isAggregate())
1978+
return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1979+
<< CXXRD << diag::OACCReductionTy::NotAgg);
20021980

20031981
for (FieldDecl *FD : RD->fields()) {
20041982
if (!IsValidMemberOfComposite(FD->getType())) {
@@ -2007,17 +1985,37 @@ ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
20071985
<< FD->getName() << RD->getName();
20081986
Notes.push_back({FD->getBeginLoc(), PD});
20091987
// TODO: member here.note_acc_reduction_member_of_composite
2010-
EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
2011-
<< FD->getType()
2012-
<< diag::OACCReductionTy::MemberNotScalar);
2013-
return ExprError();
1988+
return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1989+
<< FD->getType()
1990+
<< diag::OACCReductionTy::MemberNotScalar);
20141991
}
20151992
}
20161993
} else {
2017-
EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
2018-
<< CurType << diag::OACCReductionTy::NotScalar);
1994+
return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)
1995+
<< CurType
1996+
<< diag::OACCReductionTy::NotScalar);
20191997
}
20201998

1999+
return false;
2000+
}
2001+
2002+
/// OpenACC 3.3 section 2.5.15:
2003+
/// At a mininmum, the supported data types include ... the numerical data types
2004+
/// in C, C++, and Fortran.
2005+
///
2006+
/// If the reduction var is a composite variable, each
2007+
/// member of the composite variable must be a supported datatype for the
2008+
/// reduction operation.
2009+
ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind,
2010+
OpenACCReductionOperator ReductionOp,
2011+
Expr *VarExpr) {
2012+
// For now, we only support 'scalar' types, or composites/arrays of scalar
2013+
// types.
2014+
VarExpr = VarExpr->IgnoreParenCasts();
2015+
2016+
if (CheckReductionVarType(VarExpr))
2017+
return ExprError();
2018+
20212019
// OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same
20222020
// reduction 'var' must have the same reduction operator.
20232021
if (!VarExpr->isInstantiationDependent()) {

clang/test/SemaOpenACC/combined-construct-reduction-clause.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,19 +166,17 @@ void uses(unsigned Parm) {
166166

167167
CompositeHasComposite CoCArr[5];
168168
// expected-error@+4{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
169-
// expected-note@+3{{used as element type of array type 'CompositeHasComposite'}}
169+
// expected-note@+3{{used as element type of array type 'CompositeHasComposite[5]'}}
170170
// expected-note@#COS_FIELD{{used as field 'COS' of composite 'CompositeHasComposite'}}
171171
// expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}}
172172
#pragma acc parallel loop reduction(+:CoCArr)
173173
for(int i = 0; i < 5; ++i);
174-
// expected-error@+4{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
175-
// expected-note@+3{{used as element type of array type 'CompositeHasComposite[5]'}}
174+
// expected-error@+3{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
176175
// expected-note@#COS_FIELD{{used as field 'COS' of composite 'CompositeHasComposite'}}
177176
// expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}}
178177
#pragma acc parallel loop reduction(+:CoCArr[3])
179178
for(int i = 0; i < 5; ++i);
180-
// expected-error@+4{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
181-
// expected-note@+3{{used as element type of sub-array type 'CompositeHasComposite'}}
179+
// expected-error@+3{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
182180
// expected-note@#COS_FIELD{{used as field 'COS' of composite 'CompositeHasComposite'}}
183181
// expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}}
184182
#pragma acc parallel loop reduction(+:CoCArr[1:1])

clang/test/SemaOpenACC/compute-construct-reduction-clause.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ void uses(unsigned Parm) {
7272
while (1);
7373

7474
struct CompositeHasComposite ChCArray[5];
75-
// expected-error@+4{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
76-
// expected-note@+3{{used as element type of sub-array type 'struct CompositeHasComposite'}}
75+
// expected-error@+3{{invalid type 'struct CompositeOfScalars' used in OpenACC 'reduction' variable reference; type is not a scalar value}}
7776
// expected-note@#COS_FIELD{{used as field 'COS' of composite 'CompositeHasComposite'}}
7877
// expected-note@+1{{OpenACC 'reduction' variable reference must be a scalar variable or a composite of scalars, or an array, sub-array, or element of scalar types}}
7978
#pragma acc parallel reduction(&: CoS, Array[I], ChCArray[0:I])

0 commit comments

Comments
 (0)