Refine volatile handling, specifically, we must have the canonical
type to look at the volatile specifier.  I found these all from just
hand auditing the code.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85967 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 265823e..a8ea752 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -698,7 +698,7 @@
 /// with location to warn on and the source range[s] to report with the
 /// warning.
 bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
-                                  SourceRange &R2) const {
+                                  SourceRange &R2, ASTContext &Ctx) const {
   // Don't warn if the expr is type dependent. The type could end up
   // instantiating to void.
   if (isTypeDependent())
@@ -711,7 +711,7 @@
     return true;
   case ParenExprClass:
     return cast<ParenExpr>(this)->getSubExpr()->
-      isUnusedResultAWarning(Loc, R1, R2);
+      isUnusedResultAWarning(Loc, R1, R2, Ctx);
   case UnaryOperatorClass: {
     const UnaryOperator *UO = cast<UnaryOperator>(this);
 
@@ -724,17 +724,18 @@
       return false;  // Not a warning.
     case UnaryOperator::Deref:
       // Dereferencing a volatile pointer is a side-effect.
-      if (getType().isVolatileQualified())
+      if (Ctx.getCanonicalType(getType()).isVolatileQualified())
         return false;
       break;
     case UnaryOperator::Real:
     case UnaryOperator::Imag:
       // accessing a piece of a volatile complex is a side-effect.
-      if (UO->getSubExpr()->getType().isVolatileQualified())
+      if (Ctx.getCanonicalType(UO->getSubExpr()->getType())
+          .isVolatileQualified())
         return false;
       break;
     case UnaryOperator::Extension:
-      return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
+      return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
     }
     Loc = UO->getOperatorLoc();
     R1 = UO->getSubExpr()->getSourceRange();
@@ -744,8 +745,8 @@
     const BinaryOperator *BO = cast<BinaryOperator>(this);
     // Consider comma to have side effects if the LHS or RHS does.
     if (BO->getOpcode() == BinaryOperator::Comma)
-      return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2) ||
-             BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2);
+      return (BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) ||
+              BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
 
     if (BO->isAssignmentOp())
       return false;
@@ -762,15 +763,15 @@
     // warning, warn about them.
     const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
     if (Exp->getLHS() &&
-        Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2))
+        Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
       return true;
-    return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2);
+    return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
   }
 
   case MemberExprClass:
     // If the base pointer or element is to a volatile pointer/field, accessing
     // it is a side effect.
-    if (getType().isVolatileQualified())
+    if (Ctx.getCanonicalType(getType()).isVolatileQualified())
       return false;
     Loc = cast<MemberExpr>(this)->getMemberLoc();
     R1 = SourceRange(Loc, Loc);
@@ -780,7 +781,7 @@
   case ArraySubscriptExprClass:
     // If the base pointer or element is to a volatile pointer/field, accessing
     // it is a side effect.
-    if (getType().isVolatileQualified())
+    if (Ctx.getCanonicalType(getType()).isVolatileQualified())
       return false;
     Loc = cast<ArraySubscriptExpr>(this)->getRBracketLoc();
     R1 = cast<ArraySubscriptExpr>(this)->getLHS()->getSourceRange();
@@ -838,7 +839,7 @@
     const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
     if (!CS->body_empty())
       if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
-        return E->isUnusedResultAWarning(Loc, R1, R2);
+        return E->isUnusedResultAWarning(Loc, R1, R2, Ctx);
 
     Loc = cast<StmtExpr>(this)->getLParenLoc();
     R1 = getSourceRange();
@@ -856,20 +857,20 @@
     // If this is a cast to void, check the operand.  Otherwise, the result of
     // the cast is unused.
     if (getType()->isVoidType())
-      return cast<CastExpr>(this)->getSubExpr()
-               ->isUnusedResultAWarning(Loc, R1, R2);
+      return (cast<CastExpr>(this)->getSubExpr()
+              ->isUnusedResultAWarning(Loc, R1, R2, Ctx));
     Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
     R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
     return true;
 
   case ImplicitCastExprClass:
     // Check the operand, since implicit casts are inserted by Sema
-    return cast<ImplicitCastExpr>(this)
-      ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
+    return (cast<ImplicitCastExpr>(this)
+            ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
 
   case CXXDefaultArgExprClass:
-    return cast<CXXDefaultArgExpr>(this)
-      ->getExpr()->isUnusedResultAWarning(Loc, R1, R2);
+    return (cast<CXXDefaultArgExpr>(this)
+            ->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
 
   case CXXNewExprClass:
     // FIXME: In theory, there might be new expressions that don't have side
@@ -877,11 +878,11 @@
   case CXXDeleteExprClass:
     return false;
   case CXXBindTemporaryExprClass:
-    return cast<CXXBindTemporaryExpr>(this)
-      ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
+    return (cast<CXXBindTemporaryExpr>(this)
+            ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
   case CXXExprWithTemporariesClass:
-    return cast<CXXExprWithTemporaries>(this)
-      ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
+    return (cast<CXXExprWithTemporaries>(this)
+            ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
   }
 }
 
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index c70d05e..7862c57 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -167,7 +167,7 @@
 
   bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
   bool VisitDeclRefExpr(DeclRefExpr *E) {
-    if (E->getType().isVolatileQualified())
+    if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
       return true;
     return false;
   }
@@ -197,7 +197,7 @@
   bool VisitUnaryPreDec(UnaryOperator *E) { return true; }
   bool VisitUnaryPostDec(UnaryOperator *E) { return true; }
   bool VisitUnaryDeref(UnaryOperator *E) {
-    if (E->getType().isVolatileQualified())
+    if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
       return true;
     return Visit(E->getSubExpr());
   }
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 06a17ff..95f073c 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -71,16 +71,17 @@
 
   const Expr *Init = D.getInit();
   QualType T = D.getType();
+  bool isVolatile = getContext().getCanonicalType(T).isVolatileQualified();
 
   if (T->isReferenceType()) {
     ErrorUnsupported(Init, "global variable that binds to a reference");
   } else if (!hasAggregateLLVMType(T)) {
     llvm::Value *V = EmitScalarExpr(Init);
-    EmitStoreOfScalar(V, DeclPtr, T.isVolatileQualified(), T);
+    EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
   } else if (T->isAnyComplexType()) {
-    EmitComplexExprIntoAddr(Init, DeclPtr, T.isVolatileQualified());
+    EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
   } else {
-    EmitAggExpr(Init, DeclPtr, T.isVolatileQualified());
+    EmitAggExpr(Init, DeclPtr, isVolatile);
 
     if (const RecordType *RT = T->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 8e445de..4f8aef4 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -417,17 +417,18 @@
       Loc = Builder.CreateStructGEP(DeclPtr, getByRefValueLLVMField(&D), 
                                     D.getNameAsString());
 
+    bool isVolatile = (getContext().getCanonicalType(D.getType())
+                       .isVolatileQualified());
     if (Ty->isReferenceType()) {
       RValue RV = EmitReferenceBindingToExpr(Init, Ty, /*IsInitializer=*/true);
       EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty);
     } else if (!hasAggregateLLVMType(Init->getType())) {
       llvm::Value *V = EmitScalarExpr(Init);
-      EmitStoreOfScalar(V, Loc, D.getType().isVolatileQualified(),
-                        D.getType());
+      EmitStoreOfScalar(V, Loc, isVolatile, D.getType());
     } else if (Init->getType()->isAnyComplexType()) {
-      EmitComplexExprIntoAddr(Init, Loc, D.getType().isVolatileQualified());
+      EmitComplexExprIntoAddr(Init, Loc, isVolatile);
     } else {
-      EmitAggExpr(Init, Loc, D.getType().isVolatileQualified());
+      EmitAggExpr(Init, Loc, isVolatile);
     }
   }
 
@@ -556,6 +557,7 @@
   assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
          "Invalid argument to EmitParmDecl");
   QualType Ty = D.getType();
+  CanQualType CTy = getContext().getCanonicalType(Ty);
 
   llvm::Value *DeclPtr;
   if (!Ty->isConstantSizeType()) {
@@ -572,7 +574,7 @@
       DeclPtr->setName(Name.c_str());
 
       // Store the initial value into the alloca.
-      EmitStoreOfScalar(Arg, DeclPtr, Ty.isVolatileQualified(), Ty);
+      EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Ty);
     } else {
       // Otherwise, if this is an aggregate, just use the input pointer.
       DeclPtr = Arg;
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 4bff8c4..96b58d8 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1648,9 +1648,10 @@
 /// expression is cheap enough and side-effect-free enough to evaluate
 /// unconditionally instead of conditionally.  This is used to convert control
 /// flow into selects in some cases.
-static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E) {
+static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
+                                                   CodeGenFunction &CGF) {
   if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))
-    return isCheapEnoughToEvaluateUnconditionally(PE->getSubExpr());
+    return isCheapEnoughToEvaluateUnconditionally(PE->getSubExpr(), CGF);
 
   // TODO: Allow anything we can constant fold to an integer or fp constant.
   if (isa<IntegerLiteral>(E) || isa<CharacterLiteral>(E) ||
@@ -1661,7 +1662,9 @@
   // X and Y are local variables.
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
-      if (VD->hasLocalStorage() && !VD->getType().isVolatileQualified())
+      if (VD->hasLocalStorage() && !(CGF.getContext()
+                                     .getCanonicalType(VD->getType())
+                                     .isVolatileQualified()))
         return true;
 
   return false;
@@ -1690,8 +1693,9 @@
   // If this is a really simple expression (like x ? 4 : 5), emit this as a
   // select instead of as control flow.  We can only do this if it is cheap and
   // safe to evaluate the LHS and RHS unconditionally.
-  if (E->getLHS() && isCheapEnoughToEvaluateUnconditionally(E->getLHS()) &&
-      isCheapEnoughToEvaluateUnconditionally(E->getRHS())) {
+  if (E->getLHS() && isCheapEnoughToEvaluateUnconditionally(E->getLHS(),
+                                                            CGF) &&
+      isCheapEnoughToEvaluateUnconditionally(E->getRHS(), CGF)) {
     llvm::Value *CondV = CGF.EvaluateExprAsBool(E->getCond());
     llvm::Value *LHS = Visit(E->getLHS());
     llvm::Value *RHS = Visit(E->getRHS());
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 893f1ed..9bb2196 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -517,7 +517,7 @@
   //===--------------------------------------------------------------------===//
 
   Qualifiers MakeQualifiers(QualType T) {
-    Qualifiers Quals = T.getQualifiers();
+    Qualifiers Quals = getContext().getCanonicalType(T).getQualifiers();
     Quals.setObjCGCAttr(getContext().getObjCGCAttrKind(T));
     return Quals;
   }
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 1453424..6a65bd1 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -70,7 +70,7 @@
 
   SourceLocation Loc;
   SourceRange R1, R2;
-  if (!E->isUnusedResultAWarning(Loc, R1, R2))
+  if (!E->isUnusedResultAWarning(Loc, R1, R2, Context))
     return;
 
   // Okay, we have an unused result.  Depending on what the base expression is,