aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp18
1 files changed, 12 insertions, 6 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index b4da999..0b7b6cd 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2934,8 +2934,9 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
// For everyhing else, use local variables.
if (SubExprT) {
bool IsConst = SubExpr->getType().isConstQualified();
- unsigned LocalIndex =
- allocateLocalPrimitive(E, *SubExprT, IsConst, E->getExtendingDecl());
+ bool IsVolatile = SubExpr->getType().isVolatileQualified();
+ unsigned LocalIndex = allocateLocalPrimitive(
+ E, *SubExprT, IsConst, IsVolatile, E->getExtendingDecl());
if (!this->visit(SubExpr))
return false;
if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
@@ -4452,6 +4453,9 @@ bool Compiler<Emitter>::visitAssignment(const Expr *LHS, const Expr *RHS,
if (!this->visit(LHS))
return false;
+ if (LHS->getType().isVolatileQualified())
+ return this->emitInvalidStore(LHS->getType().getTypePtr(), E);
+
// We don't support assignments in C.
if (!Ctx.getLangOpts().CPlusPlus && !this->emitInvalid(E))
return false;
@@ -4560,13 +4564,14 @@ bool Compiler<Emitter>::emitConst(const APSInt &Value, const Expr *E) {
template <class Emitter>
unsigned Compiler<Emitter>::allocateLocalPrimitive(
- DeclTy &&Src, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl,
- ScopeKind SC, bool IsConstexprUnknown) {
+ DeclTy &&Src, PrimType Ty, bool IsConst, bool IsVolatile,
+ const ValueDecl *ExtendingDecl, ScopeKind SC, bool IsConstexprUnknown) {
// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
// (int){12} in C. Consider using Expr::isTemporaryObject() instead
// or isa<MaterializeTemporaryExpr>().
Descriptor *D = P.createDescriptor(Src, Ty, nullptr, Descriptor::InlineDescMD,
- IsConst, isa<const Expr *>(Src));
+ IsConst, isa<const Expr *>(Src),
+ /*IsMutable=*/false, IsVolatile);
D->IsConstexprUnknown = IsConstexprUnknown;
Scope::Local Local = this->createLocal(D);
if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>()))
@@ -4874,7 +4879,8 @@ Compiler<Emitter>::visitVarDecl(const VarDecl *VD, const Expr *Init,
if (VarT) {
unsigned Offset = this->allocateLocalPrimitive(
- VD, *VarT, VD->getType().isConstQualified(), nullptr, ScopeKind::Block,
+ VD, *VarT, VD->getType().isConstQualified(),
+ VD->getType().isVolatileQualified(), nullptr, ScopeKind::Block,
IsConstexprUnknown);
if (Init) {
// If this is a toplevel declaration, create a scope for the