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));
   }
 }