@@ -46,6 +46,12 @@ std::string ConstraintVariable::getRewritableOriginalTy() const {
46
46
return OrigTyString;
47
47
}
48
48
49
+ std::string ConstraintVariable::getOriginalTypeWithName () const {
50
+ if (Name == RETVAR)
51
+ return getRewritableOriginalTy ();
52
+ return OriginalTypeWithName;
53
+ }
54
+
49
55
PointerVariableConstraint *PointerVariableConstraint::getWildPVConstraint (
50
56
Constraints &CS, const std::string &Rsn, PersistentSourceLoc *PSL) {
51
57
auto *WildPVC = new PointerVariableConstraint (" wildvar" );
@@ -121,9 +127,9 @@ PointerVariableConstraint *PointerVariableConstraint::addAtomPVConstraint(
121
127
PointerVariableConstraint::PointerVariableConstraint (
122
128
PointerVariableConstraint *Ot)
123
129
: ConstraintVariable(ConstraintVariable::PointerVariable, Ot->OriginalType,
124
- Ot->Name), BaseType( Ot->BaseType), Vars(Ot->Vars ),
125
- SrcVars (Ot->SrcVars ), FV (Ot->FV ), QualMap (Ot->QualMap ),
126
- ArrSizes(Ot->ArrSizes), ArrSizeStrs(Ot->ArrSizeStrs),
130
+ Ot->Name, Ot->OriginalTypeWithName ),
131
+ BaseType (Ot->BaseType ), Vars (Ot->Vars ), SrcVars (Ot->SrcVars), FV(Ot->FV ),
132
+ QualMap(Ot->QualMap), ArrSizes(Ot->ArrSizes), ArrSizeStrs(Ot->ArrSizeStrs),
127
133
SrcHasItype(Ot->SrcHasItype), ItypeStr(Ot->ItypeStr),
128
134
PartOfFuncPrototype(Ot->PartOfFuncPrototype), Parent(Ot),
129
135
BoundsAnnotationStr(Ot->BoundsAnnotationStr),
@@ -206,7 +212,7 @@ PointerVariableConstraint::PointerVariableConstraint(
206
212
const ASTContext &C, std::string *InFunc, int ForceGenericIndex,
207
213
bool PotentialGeneric,
208
214
bool VarAtomForChecked, TypeSourceInfo *TSInfo, const QualType &ITypeT)
209
- : ConstraintVariable(ConstraintVariable::PointerVariable, qtyToStr(QT) , N),
215
+ : ConstraintVariable(ConstraintVariable::PointerVariable, QT , N),
210
216
FV(nullptr ), SrcHasItype(false ), PartOfFuncPrototype(InFunc != nullptr ),
211
217
Parent(nullptr ) {
212
218
QualType QTy = QT;
@@ -512,7 +518,7 @@ PointerVariableConstraint::PointerVariableConstraint(
512
518
// tn fname = ...,
513
519
// where tn is the typedef'ed type name.
514
520
// There is possibly something more elegant to do in the code here.
515
- FV = new FVConstraint (Ty , IsDeclTy ? D : nullptr , IsTypedef ? " " : N, I, C,
521
+ FV = new FVConstraint (QTy , IsDeclTy ? D : nullptr , IsTypedef ? " " : N, I, C,
516
522
TSInfo);
517
523
518
524
// Get a string representing the type without pointer and array indirection.
@@ -965,8 +971,11 @@ PointerVariableConstraint::mkString(Constraints &CS,
965
971
}
966
972
967
973
// No space after itype.
968
- if (!EmittedName && !UseName.empty ())
969
- Ss << " " << UseName;
974
+ if (!EmittedName && !UseName.empty ()) {
975
+ if (!StringRef (Ss.str ()).endswith (" *" ))
976
+ Ss << " " ;
977
+ Ss << UseName;
978
+ }
970
979
971
980
// Final array dropping.
972
981
if (!ConstArrs.empty ()) {
@@ -1004,10 +1013,10 @@ const CVarSet &PVConstraint::getArgumentConstraints() const {
1004
1013
1005
1014
FunctionVariableConstraint::FunctionVariableConstraint (FVConstraint *Ot)
1006
1015
: ConstraintVariable(ConstraintVariable::FunctionVariable, Ot->OriginalType,
1007
- Ot->getName ()), ReturnVar( Ot->ReturnVar ),
1008
- ParamVars (Ot->ParamVars ), FileName (Ot->FileName ), Hasproto (Ot->Hasproto ),
1009
- Hasbody (Ot->Hasbody ), IsStatic (Ot->IsStatic ), Parent (Ot),
1010
- IsFunctionPtr(Ot->IsFunctionPtr), TypeParams(Ot->TypeParams) {
1016
+ Ot->getName (), Ot->OriginalTypeWithName ),
1017
+ ReturnVar (Ot->ReturnVar ), ParamVars (Ot->ParamVars ), FileName (Ot->FileName ),
1018
+ Hasproto (Ot->Hasproto ), Hasbody (Ot->Hasbody ), IsStatic (Ot->IsStatic ),
1019
+ Parent(Ot), IsFunctionPtr(Ot->IsFunctionPtr), TypeParams(Ot->TypeParams) {
1011
1020
this ->HasEqArgumentConstraints = Ot->HasEqArgumentConstraints ;
1012
1021
}
1013
1022
@@ -1019,22 +1028,23 @@ FunctionVariableConstraint::FunctionVariableConstraint(DeclaratorDecl *D,
1019
1028
ProgramInfo &I,
1020
1029
const ASTContext &C)
1021
1030
: FunctionVariableConstraint(
1022
- D->getType ().getTypePtr() , D,
1031
+ D->getType (), D,
1023
1032
D->getDeclName().isIdentifier() ? std::string(D->getName ()) : "", I,
1024
1033
C, D->getTypeSourceInfo()) {}
1025
1034
1026
1035
FunctionVariableConstraint::FunctionVariableConstraint (TypedefDecl *D,
1027
1036
ProgramInfo &I,
1028
1037
const ASTContext &C)
1029
- : FunctionVariableConstraint(D->getUnderlyingType ().getTypePtr() , nullptr,
1038
+ : FunctionVariableConstraint(D->getUnderlyingType (), nullptr,
1030
1039
D->getNameAsString(), I, C,
1031
1040
D->getTypeSourceInfo()) {}
1032
1041
1033
1042
FunctionVariableConstraint::FunctionVariableConstraint (
1034
- const Type *Ty , DeclaratorDecl *D, std::string N, ProgramInfo &I,
1043
+ const QualType QT , DeclaratorDecl *D, std::string N, ProgramInfo &I,
1035
1044
const ASTContext &Ctx, TypeSourceInfo *TSInfo)
1036
- : ConstraintVariable(ConstraintVariable::FunctionVariable, tyToStr(Ty) , N),
1045
+ : ConstraintVariable(ConstraintVariable::FunctionVariable, QT , N),
1037
1046
Parent(nullptr ) {
1047
+ const Type *Ty = QT.getTypePtr ();
1038
1048
QualType RT, RTIType;
1039
1049
Hasproto = false ;
1040
1050
Hasbody = false ;
@@ -2004,8 +2014,10 @@ void PointerVariableConstraint::mergeDeclaration(ConstraintVariable *FromCV,
2004
2014
" Merging error, pointer depth change" );
2005
2015
Vars = NewVAtoms;
2006
2016
SrcVars = NewSrcAtoms;
2007
- if (Name.empty ())
2017
+ if (Name.empty ()) {
2008
2018
Name = From->Name ;
2019
+ OriginalTypeWithName = From->OriginalTypeWithName ;
2020
+ }
2009
2021
SrcHasItype = SrcHasItype || From->SrcHasItype ;
2010
2022
if (!From->ItypeStr .empty ())
2011
2023
ItypeStr = From->ItypeStr ;
@@ -2265,16 +2277,20 @@ void FVComponentVariable::equateWithItype(ProgramInfo &I,
2265
2277
? " Internal constraint for generic function declaration, "
2266
2278
" for which 3C currently does not support re-solving."
2267
2279
: ReasonUnchangeable;
2268
- bool HasBounds = ExternalConstraint->srcHasBounds ();
2269
2280
bool HasItype = ExternalConstraint->srcHasItype ();
2270
2281
// If the type cannot change at all (ReasonUnchangeable2 is set), then we
2271
- // constrain both the external and internal types to not change. Otherwise, if
2272
- // the variable has bounds, then we don't want the checked (external) portion
2273
- // of the type to change because that could blow away the bounds, but we still
2274
- // allow the internal type to change so that the type can change from an itype
2275
- // to fully checked.
2282
+ // constrain both the external and internal types to not change.
2276
2283
bool MustConstrainInternalType = !ReasonUnchangeable2.empty ();
2277
- if (HasItype && (MustConstrainInternalType || HasBounds)) {
2284
+ // Otherwise, if a pointer is an array pointer with declared bounds or is a
2285
+ // constant size array, then we want to ensure the external type continues to
2286
+ // solve to ARR or NTARR; see the comment on
2287
+ // ConstraintVariable::equateWithItype re how this is achieved. This avoids
2288
+ // losing bounds on array pointers, and converting constant sized arrays into
2289
+ // pointers. We still allow the internal type to change so that the type can
2290
+ // change from an itype to fully checked.
2291
+ bool MustBeArray =
2292
+ ExternalConstraint->srcHasBounds () || ExternalConstraint->hasSomeSizedArr ();
2293
+ if (HasItype && (MustConstrainInternalType || MustBeArray)) {
2278
2294
ExternalConstraint->equateWithItype (I, ReasonUnchangeable2, PSL);
2279
2295
if (ExternalConstraint != InternalConstraint)
2280
2296
linkInternalExternal (I, false );
0 commit comments