Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -1608,7 +1608,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue, SourceLocation Loc) { - return EmitLoadOfScalar(lvalue.getAddress(*this), lvalue.isVolatile(), + return EmitLoadOfScalar(lvalue.getAddress(*this),lvalue.isVolatile() | isVolatileCastStmt, lvalue.getType(), Loc, lvalue.getBaseInfo(), lvalue.getTBAAInfo(), lvalue.isNontemporal()); } @@ -4805,6 +4805,9 @@ // bound and change the IR type. // FIXME: Once pointee types are removed from IR, remove this. LValue LV = EmitLValue(E->getSubExpr()); + // Propagate the volatile qualifer to LValue, if exist in E. + if (E->getType().isVolatileQualified()) + LV.getQuals().addVolatile(); if (LV.isSimple()) { Address V = LV.getAddress(*this); if (V.isValid()) { Index: clang/lib/CodeGen/CGExprScalar.cpp =================================================================== --- clang/lib/CodeGen/CGExprScalar.cpp +++ clang/lib/CodeGen/CGExprScalar.cpp @@ -2225,6 +2225,20 @@ return Visit(const_cast(E)); case CK_NoOp: { + // Propagate the volatileness if Casted to volatile like + // + // |-ImplicitCastExpr 'int' + // | `-CXXStaticCastExpr 'volatile int' lvalue static_cast + // | `-ImplicitCastExpr 'volatile int' lvalue part_of_explicit_cast + // | `-DeclRefExpr 'int' lvalue Var 0x55556b04caa0 'x' 'int' + // + // Later required to emit the load inst accrodingly. + if (!CGF.isVolatileCastStmt && CE->getType().isVolatileQualified()) + CGF.isVolatileCastStmt= true; + // Reset if set and CastStnt doesn't required in general. + else if (CGF.isVolatileCastStmt && !CE->getType().isVolatileQualified()) + CGF.isVolatileCastStmt= false; + llvm::Value *V = Visit(const_cast(E)); if (V) { // CK_NoOp can model a pointer qualification conversion, which can remove Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -545,6 +545,10 @@ /// potentially set the return value. bool SawAsmBlock = false; + /// Propagate the volatileness to the reference decl node in the CastStmt + // Note the decl node doesn't has be the volatile qualifier. + bool isVolatileCastStmt = false; + GlobalDecl CurSEHParent; /// True if the current function is an outlined SEH helper. This can be a Index: clang/test/CodeGen/volatile.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/volatile.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm < %s | FileCheck %s -check-prefix CHECK + +int x ; +void f0() { + const_cast(x) = const_cast(x) + 1; +// CHECK: %0 = load volatile i32, ptr @x +// CHECK: %add = add nsw i32 %0, 1 +// CHECK: store volatile i32 %add, ptr @x + static_cast(x) = static_cast(x) + 1; +// CHECK: %1 = load volatile i32, ptr @x +// CHECK: %add1 = add nsw i32 %1, 1 +// CHECK: store volatile i32 %add1, ptr @x +}