-
Notifications
You must be signed in to change notification settings - Fork 0
Contracts nightly #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: contracts-base
Are you sure you want to change the base?
Changes from all commits
dd5ce67
de83929
3a3d504
1f0e34b
d63f11e
bb979cd
2c6d5fd
249f571
4eee4d5
b039625
6b6d951
9674f45
93a6ba5
4b91b34
670df13
33eaf39
c8290ce
d19459f
acd41cd
c6eac65
6071299
391ac51
d399ebf
33d86bf
dd4fb76
10d6946
3653205
138ce13
3fa7f33
5053299
1b41645
a21af21
4375eca
e11ee1f
5baf4fb
ea09d6a
8f168e8
8ad85a3
f87514d
e68de9f
0d848f3
c5c572b
ff28a02
8e108c3
c973386
deee849
c90146c
2496eb1
eb20a06
859c7cc
eba4e9b
1c7ca5f
bb6bc4d
008b9f8
a0696f1
5bd7502
eeaf4c8
7593ea5
e42e0da
1853eda
8f3798b
5d3fe34
7d538a6
20d89bc
1cd86ae
1983bc6
aa460bb
dd42a17
7b5d440
636379d
d8aa52a
bff0015
b3a7912
7a13879
00a37e6
43f9a99
ce40d46
94962a0
fa665c9
42aede0
7b2d493
8410ea6
7f73aed
d435b4b
acd8756
c21ac2e
ca97bd8
f876563
f29f4d8
790e248
e2823ad
e406e30
736cd30
39b13ff
be3618e
ead688e
d8ce14a
b86bb4f
2a95f50
0536778
19200f3
7b35443
97ee8da
9c7e575
f0c696e
e1eae95
0e11e7e
1a8691e
d8fa6bf
55c0115
a4bbee1
b6111fa
5cdd5ff
d00bcda
a8fec54
a825f44
41eb0e6
bde79ad
ff224b5
03703a6
1b34713
33117f7
8ae4b0f
ad37382
624e117
c085a7b
f5bd830
98b8658
28bc937
aae32af
fdbd394
4f16753
9b48c77
306f147
2f53e1c
bfd1dd9
99b70b6
01c0a7b
654a052
5cfd1fa
8b799fa
7b8a2c0
1e0fa51
0ea44a7
cf071e8
1bfef1b
c948813
1ce21f0
d4cc62e
45a17da
88ae701
5754fed
4a726dc
e08f16b
e845f32
0fdd326
7477b44
d45524d
f58bb13
3f77a05
741163d
7a59c2f
32ffa4f
0852a7b
189f6ff
07a81cc
6667568
7c23886
d456da7
7793c0e
aeba9b9
ee4919f
9de4341
aed147b
441e5bd
962b8e9
7c8a3cb
fb45504
784686d
8ee401f
f3615bf
7f7246e
6b78e30
c49705f
d2a5be8
7d383f0
f1e4683
1c27de9
e8dfec8
1f8ffc0
01c3f80
ceadf96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
name: EricWF Contracts Nightly Release flow | ||
|
||
permissions: | ||
contents: write | ||
actions: read | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- 'eric-contracts' | ||
- "eric-test-contracts" | ||
|
||
|
||
concurrency: | ||
# Skip intermediate builds: always. | ||
# Cancel intermediate builds: only if it is a pull request build. | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} | ||
|
||
jobs: | ||
check_clang: | ||
name: "Do it" | ||
if: github.repository_owner == 'EricWF' | ||
runs-on: aah | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
ref: ${{ github.ref }} | ||
fetch-depth: 0 | ||
- name: "Setup" | ||
run: | | ||
mkdir build | ||
mkdir install | ||
|
||
- name: "Configure" | ||
run: > | ||
cmake -B build -S ./llvm/ | ||
-G Ninja | ||
-DCMAKE_BUILD_TYPE=RELWITHDEBINFO | ||
-DLLVM_ENABLE_PROJECTS="clang" | ||
"-DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi;libunwind" | ||
-DLLVM_ENABLE_ASSERTIONS=ON | ||
-DLLVM_USE_LINKER=mold | ||
-DCMAKE_INSTALL_PREFIX=./install | ||
-DCMAKE_C_COMPILER=clang | ||
-DCMAKE_CXX_COMPILER=clang++ | ||
'-DLLVM_USE_SANITIZER=Address;Undefined' | ||
- name: Build Clang & Libc++ | ||
run: | | ||
cd build | ||
ninja clang | ||
ninja cxx | ||
- name: Test Clang | ||
run: | | ||
cd build | ||
ninja check-clang | ||
- name: Check Libc++ | ||
run: | | ||
cd build | ||
ninja check-cxx | ||
- name: Install | ||
run: | | ||
cd build | ||
ninja install |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
* Parse result name in post contracts | ||
* auto declared functions. | ||
* templates. | ||
* Late parsing in general | ||
* Diagnose | ||
* Test parsing failures | ||
* What happens when pre/post throws from a noexcept function? Can we even callee-emit contracts? | ||
* Start constification | ||
* Check 'this' access in pre/post | ||
* Codegen: | ||
* Make it work | ||
|
||
* Required headers? | ||
<contracts> | ||
<source_location> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1321,6 +1321,10 @@ class ASTContext : public RefCountedBase<ASTContext> { | |
// The decl is built when constructing 'BuiltinVaListDecl'. | ||
mutable Decl *VaListTagDecl = nullptr; | ||
|
||
// Decl used to define the datastructure for the contract violation object | ||
// used for C++ contracts | ||
mutable Decl *BuiltinContractViolationRecordDecl = nullptr; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason not to make that a RecordDecl directly? |
||
|
||
// Implicitly-declared type 'struct _GUID'. | ||
mutable TagDecl *MSGuidTagDecl = nullptr; | ||
|
||
|
@@ -2446,6 +2450,17 @@ class ASTContext : public RefCountedBase<ASTContext> { | |
return getCanonicalTagType(MSGuidTagDecl); | ||
} | ||
|
||
CanQualType getBuiltinContractViolationRecordType() const { | ||
return getCanonicalTagType( | ||
cast<RecordDecl>(getBuiltinContractViolationRecordDecl())); | ||
} | ||
|
||
Decl *getBuiltinContractViolationRecordDecl() const; | ||
UnnamedGlobalConstantDecl * | ||
BuildViolationObject(const ContractStmt *CS, | ||
const FunctionDecl *CurDecl = nullptr); | ||
|
||
|
||
/// Retrieve the implicitly-predeclared 'struct type_info' declaration. | ||
TagDecl *getMSTypeInfoTagDecl() const { | ||
// Lazily create this type on demand - it's only needed for MS builds. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,7 +159,7 @@ class ASTNodeTraverser | |
|
||
// Some statements have custom mechanisms for dumping their children. | ||
if (isa<DeclStmt, GenericSelectionExpr, RequiresExpr, | ||
OpenACCWaitConstruct, SYCLKernelCallStmt>(S)) | ||
OpenACCWaitConstruct, SYCLKernelCallStmt, ContractStmt>(S)) | ||
Comment on lines
161
to
+162
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should just make expressions children. It's not yet clear to me why they should not be, as I do a linear read through |
||
return; | ||
|
||
if (Traversal == TK_IgnoreUnlessSpelledInSource && | ||
|
@@ -556,6 +556,9 @@ class ASTNodeTraverser | |
if (const AssociatedConstraint &TRC = D->getTrailingRequiresClause()) | ||
Visit(TRC.ConstraintExpr); | ||
|
||
if (const ContractSpecifierDecl *CSD = D->getContracts()) | ||
Visit(CSD); | ||
|
||
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted()) | ||
return; | ||
|
||
|
@@ -747,6 +750,17 @@ class ASTNodeTraverser | |
Visit(D->getConstraintExpr()); | ||
} | ||
|
||
void VisitContractSpecifierDecl(const ContractSpecifierDecl *CSD) { | ||
for (auto *CS : CSD->contracts()) | ||
Visit(CS); | ||
} | ||
|
||
void VisitContractStmt(const ContractStmt *S) { | ||
if (S->hasResultName()) | ||
Visit(S->getResultName()); | ||
Visit(S->getCond()); | ||
} | ||
|
||
void VisitImplicitConceptSpecializationDecl( | ||
const ImplicitConceptSpecializationDecl *CSD) { | ||
for (const TemplateArgument &Arg : CSD->getTemplateArguments()) | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -58,6 +58,8 @@ namespace clang { | |||||
class ASTContext; | ||||||
struct ASTTemplateArgumentListInfo; | ||||||
class CompoundStmt; | ||||||
class ContractStmt; | ||||||
class ContractSpecifierDecl; | ||||||
class DependentFunctionTemplateSpecializationInfo; | ||||||
class EnumDecl; | ||||||
class Expr; | ||||||
|
@@ -70,6 +72,7 @@ class Module; | |||||
class NamespaceDecl; | ||||||
class ParmVarDecl; | ||||||
class RecordDecl; | ||||||
class ResultNameDecl; | ||||||
class Stmt; | ||||||
class StringLiteral; | ||||||
class TagDecl; | ||||||
|
@@ -80,6 +83,7 @@ class TypeAliasTemplateDecl; | |||||
class UnresolvedSetImpl; | ||||||
class VarTemplateDecl; | ||||||
enum class ImplicitParamKind; | ||||||
enum class ContractKind; | ||||||
|
||||||
// Holds a constraint expression along with a pack expansion index, if | ||||||
// expanded. | ||||||
|
@@ -778,8 +782,8 @@ struct QualifierInfo { | |||||
/// Contains type source information through TypeSourceInfo. | ||||||
class DeclaratorDecl : public ValueDecl { | ||||||
// A struct representing a TInfo, a trailing requires-clause and a syntactic | ||||||
// qualifier, to be used for the (uncommon) case of out-of-line declarations | ||||||
// and constrained function decls. | ||||||
// qualifier, to be used for the (uncommon) case of out-of-line declarations, | ||||||
// constrained function decls or functions with contracts. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
struct ExtInfo : public QualifierInfo { | ||||||
TypeSourceInfo *TInfo = nullptr; | ||||||
AssociatedConstraint TrailingRequiresClause; | ||||||
|
@@ -908,17 +912,24 @@ struct EvaluatedStmt { | |||||
bool HasICEInit : 1; | ||||||
bool CheckedForICEInit : 1; | ||||||
|
||||||
// The APvalue stored here may need re-evaluation under contracts, in which | ||||||
// case we need to track if we've already regisetered this value for | ||||||
// destruction. | ||||||
bool RegisteredForDestruction : 1; | ||||||
|
||||||
bool HasSideEffects : 1; | ||||||
bool CheckedForSideEffects : 1; | ||||||
|
||||||
|
||||||
LazyDeclStmtPtr Value; | ||||||
APValue Evaluated; | ||||||
|
||||||
EvaluatedStmt() | ||||||
: WasEvaluated(false), IsEvaluating(false), | ||||||
HasConstantInitialization(false), HasConstantDestruction(false), | ||||||
HasICEInit(false), CheckedForICEInit(false), HasSideEffects(false), | ||||||
CheckedForSideEffects(false) {} | ||||||
HasICEInit(false), CheckedForICEInit(false), | ||||||
RegisteredForDestruction(false), HasSideEffects(false), CheckedForSideEffects(false) {} | ||||||
|
||||||
}; | ||||||
|
||||||
/// Represents a variable declaration or definition. | ||||||
|
@@ -1413,7 +1424,8 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { | |||||
|
||||||
private: | ||||||
APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes, | ||||||
bool IsConstantInitialization) const; | ||||||
bool IsConstantInitialization, | ||||||
bool EnableContracts) const; | ||||||
|
||||||
public: | ||||||
/// Return the already-evaluated value of this variable's | ||||||
|
@@ -1445,8 +1457,13 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { | |||||
/// Evaluate the initializer of this variable to determine whether it's a | ||||||
/// constant initializer. Should only be called once, after completing the | ||||||
/// definition of the variable. | ||||||
bool checkForConstantInitialization( | ||||||
SmallVectorImpl<PartialDiagnosticAt> &Notes) const; | ||||||
bool | ||||||
checkForConstantInitialization(SmallVectorImpl<PartialDiagnosticAt> &Notes, | ||||||
bool EnableContracts = true) const; | ||||||
|
||||||
bool | ||||||
recheckForConstantInitialization(SmallVectorImpl<PartialDiagnosticAt> &Notes, | ||||||
bool EnableContracts = true) const; | ||||||
|
||||||
void setInitStyle(InitializationStyle Style) { | ||||||
VarDeclBits.InitStyle = Style; | ||||||
|
@@ -2058,13 +2075,18 @@ class FunctionDecl : public DeclaratorDecl, | |||||
/// no formals. | ||||||
ParmVarDecl **ParamInfo = nullptr; | ||||||
|
||||||
/// The contract sequence specified on this function declaration if there is | ||||||
/// any, otherwise nullptr | ||||||
ContractSpecifierDecl *Contracts = nullptr; | ||||||
|
||||||
/// The active member of this union is determined by | ||||||
/// FunctionDeclBits.HasDefaultedOrDeletedInfo. | ||||||
union { | ||||||
/// The body of the function. | ||||||
LazyDeclStmtPtr Body; | ||||||
/// Information about a future defaulted function definition. | ||||||
DefaultedOrDeletedFunctionInfo *DefaultedOrDeletedInfo; | ||||||
/// | ||||||
}; | ||||||
|
||||||
unsigned ODRHash; | ||||||
|
@@ -2154,7 +2176,8 @@ class FunctionDecl : public DeclaratorDecl, | |||||
const DeclarationNameInfo &NameInfo, QualType T, | ||||||
TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin, | ||||||
bool isInlineSpecified, ConstexprSpecKind ConstexprKind, | ||||||
const AssociatedConstraint &TrailingRequiresClause); | ||||||
const AssociatedConstraint &TrailingRequiresClause, | ||||||
ContractSpecifierDecl *Contracts = nullptr); | ||||||
|
||||||
using redeclarable_base = Redeclarable<FunctionDecl>; | ||||||
|
||||||
|
@@ -2190,20 +2213,23 @@ class FunctionDecl : public DeclaratorDecl, | |||||
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false, | ||||||
bool isInlineSpecified = false, bool hasWrittenPrototype = true, | ||||||
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified, | ||||||
const AssociatedConstraint &TrailingRequiresClause = {}) { | ||||||
const AssociatedConstraint &TrailingRequiresClause = {}, | ||||||
ContractSpecifierDecl *Contracts = nullptr) { | ||||||
|
||||||
DeclarationNameInfo NameInfo(N, NLoc); | ||||||
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, | ||||||
UsesFPIntrin, isInlineSpecified, | ||||||
hasWrittenPrototype, ConstexprKind, | ||||||
TrailingRequiresClause); | ||||||
TrailingRequiresClause, Contracts); | ||||||
} | ||||||
|
||||||
static FunctionDecl * | ||||||
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, | ||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, | ||||||
StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified, | ||||||
bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, | ||||||
const AssociatedConstraint &TrailingRequiresClause); | ||||||
const AssociatedConstraint &TrailingRequiresClause, ContractSpecifierDecl *Contracts); | ||||||
|
||||||
|
||||||
static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); | ||||||
|
||||||
|
@@ -2765,6 +2791,10 @@ class FunctionDecl : public DeclaratorDecl, | |||||
return const_cast<FunctionDecl*>(this)->getCanonicalDecl(); | ||||||
} | ||||||
|
||||||
|
||||||
FunctionDecl *getDeclForContracts(); | ||||||
const FunctionDecl *getDeclForContracts() const; | ||||||
|
||||||
Comment on lines
+2794
to
+2797
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those are not used (and if we were to keep them we could come up with a better name) |
||||||
unsigned getBuiltinID(bool ConsiderWrapperFunctions = false) const; | ||||||
|
||||||
// ArrayRef interface to parameters. | ||||||
|
@@ -3138,6 +3168,22 @@ class FunctionDecl : public DeclaratorDecl, | |||||
return {}; | ||||||
} | ||||||
|
||||||
/// Set the function level contracts for this function. Update the specifier | ||||||
/// decl and it's children to have this declaration as a declaration context. | ||||||
void setContracts(ContractSpecifierDecl *CSD); | ||||||
|
||||||
bool hasContracts() const { return Contracts != nullptr; } | ||||||
|
||||||
ContractSpecifierDecl *getContracts() const { return Contracts; } | ||||||
|
||||||
using ContractRange = llvm::iterator_range<llvm::filter_iterator< | ||||||
ArrayRef<ContractStmt *>::iterator, bool (*)(const ContractStmt *)>>; | ||||||
|
||||||
// Convenience functions to get the preconditions and postconditions. | ||||||
ArrayRef<ContractStmt *> contracts() const; | ||||||
ContractRange preconditions() const; | ||||||
ContractRange postconditions() const; | ||||||
|
||||||
// Implement isa/cast/dyncast/etc. | ||||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); } | ||||||
static bool classofKind(Kind K) { | ||||||
|
@@ -3184,6 +3230,9 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { | |||||
unsigned Mutable : 1; | ||||||
LLVM_PREFERRED_TYPE(InitStorageKind) | ||||||
unsigned StorageKind : 2; | ||||||
LLVM_PREFERRED_TYPE(bool) | ||||||
unsigned IsConstifiedCapture : 1; | ||||||
|
||||||
mutable unsigned CachedFieldIndex : 28; | ||||||
|
||||||
/// If this is a bitfield with a default member initializer, this | ||||||
|
@@ -3223,6 +3272,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { | |||||
CachedFieldIndex(0), Init() { | ||||||
if (BW) | ||||||
setBitWidth(BW); | ||||||
IsConstifiedCapture = false; | ||||||
} | ||||||
|
||||||
public: | ||||||
|
@@ -3385,6 +3435,11 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { | |||||
/// Set the captured variable length array type for this field. | ||||||
void setCapturedVLAType(const VariableArrayType *VLAType); | ||||||
|
||||||
bool isConstifiedCapture() const { return IsConstifiedCapture; } | ||||||
void setIsConstifiedCapture(bool Value = true) { | ||||||
IsConstifiedCapture = Value; | ||||||
} | ||||||
|
||||||
/// Returns the parent of this field declaration, which | ||||||
/// is the struct in which this field is defined. | ||||||
/// | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.