1//===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides Sema routines for C++ exception specification testing.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Sema/SemaInternal.h"
15#include "clang/AST/CXXInheritance.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/ExprCXX.h"
18#include "clang/AST/TypeLoc.h"
19#include "clang/Basic/Diagnostic.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Lex/Preprocessor.h"
22#include "llvm/ADT/SmallPtrSet.h"
23#include "llvm/ADT/SmallString.h"
24
25namespace clang {
26
27static const FunctionProtoType *GetUnderlyingFunction(QualType T)
28{
29  if (const PointerType *PtrTy = T->getAs<PointerType>())
30    T = PtrTy->getPointeeType();
31  else if (const ReferenceType *RefTy = T->getAs<ReferenceType>())
32    T = RefTy->getPointeeType();
33  else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
34    T = MPTy->getPointeeType();
35  return T->getAs<FunctionProtoType>();
36}
37
38/// CheckSpecifiedExceptionType - Check if the given type is valid in an
39/// exception specification. Incomplete types, or pointers to incomplete types
40/// other than void are not allowed.
41///
42/// \param[in,out] T  The exception type. This will be decayed to a pointer type
43///                   when the input is an array or a function type.
44bool Sema::CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range) {
45  // C++11 [except.spec]p2:
46  //   A type cv T, "array of T", or "function returning T" denoted
47  //   in an exception-specification is adjusted to type T, "pointer to T", or
48  //   "pointer to function returning T", respectively.
49  //
50  // We also apply this rule in C++98.
51  if (T->isArrayType())
52    T = Context.getArrayDecayedType(T);
53  else if (T->isFunctionType())
54    T = Context.getPointerType(T);
55
56  int Kind = 0;
57  QualType PointeeT = T;
58  if (const PointerType *PT = T->getAs<PointerType>()) {
59    PointeeT = PT->getPointeeType();
60    Kind = 1;
61
62    // cv void* is explicitly permitted, despite being a pointer to an
63    // incomplete type.
64    if (PointeeT->isVoidType())
65      return false;
66  } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
67    PointeeT = RT->getPointeeType();
68    Kind = 2;
69
70    if (RT->isRValueReferenceType()) {
71      // C++11 [except.spec]p2:
72      //   A type denoted in an exception-specification shall not denote [...]
73      //   an rvalue reference type.
74      Diag(Range.getBegin(), diag::err_rref_in_exception_spec)
75        << T << Range;
76      return true;
77    }
78  }
79
80  // C++11 [except.spec]p2:
81  //   A type denoted in an exception-specification shall not denote an
82  //   incomplete type other than a class currently being defined [...].
83  //   A type denoted in an exception-specification shall not denote a
84  //   pointer or reference to an incomplete type, other than (cv) void* or a
85  //   pointer or reference to a class currently being defined.
86  if (!(PointeeT->isRecordType() &&
87        PointeeT->getAs<RecordType>()->isBeingDefined()) &&
88      RequireCompleteType(Range.getBegin(), PointeeT,
89                          diag::err_incomplete_in_exception_spec, Kind, Range))
90    return true;
91
92  return false;
93}
94
95/// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
96/// to member to a function with an exception specification. This means that
97/// it is invalid to add another level of indirection.
98bool Sema::CheckDistantExceptionSpec(QualType T) {
99  if (const PointerType *PT = T->getAs<PointerType>())
100    T = PT->getPointeeType();
101  else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
102    T = PT->getPointeeType();
103  else
104    return false;
105
106  const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
107  if (!FnT)
108    return false;
109
110  return FnT->hasExceptionSpec();
111}
112
113const FunctionProtoType *
114Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {
115  if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
116    return FPT;
117
118  FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl();
119  const FunctionProtoType *SourceFPT =
120      SourceDecl->getType()->castAs<FunctionProtoType>();
121
122  // If the exception specification has already been resolved, just return it.
123  if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType()))
124    return SourceFPT;
125
126  // Compute or instantiate the exception specification now.
127  if (SourceFPT->getExceptionSpecType() == EST_Unevaluated)
128    EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl));
129  else
130    InstantiateExceptionSpec(Loc, SourceDecl);
131
132  return SourceDecl->getType()->castAs<FunctionProtoType>();
133}
134
135/// Determine whether a function has an implicitly-generated exception
136/// specification.
137static bool hasImplicitExceptionSpec(FunctionDecl *Decl) {
138  if (!isa<CXXDestructorDecl>(Decl) &&
139      Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete &&
140      Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
141    return false;
142
143  // If the user didn't declare the function, its exception specification must
144  // be implicit.
145  if (!Decl->getTypeSourceInfo())
146    return true;
147
148  const FunctionProtoType *Ty =
149    Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>();
150  return !Ty->hasExceptionSpec();
151}
152
153bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
154  OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator();
155  bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
156  bool MissingExceptionSpecification = false;
157  bool MissingEmptyExceptionSpecification = false;
158  unsigned DiagID = diag::err_mismatched_exception_spec;
159  if (getLangOpts().MicrosoftExt)
160    DiagID = diag::warn_mismatched_exception_spec;
161
162  // Check the types as written: they must match before any exception
163  // specification adjustment is applied.
164  if (!CheckEquivalentExceptionSpec(
165        PDiag(DiagID), PDiag(diag::note_previous_declaration),
166        Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(),
167        New->getType()->getAs<FunctionProtoType>(), New->getLocation(),
168        &MissingExceptionSpecification, &MissingEmptyExceptionSpecification,
169        /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) {
170    // C++11 [except.spec]p4 [DR1492]:
171    //   If a declaration of a function has an implicit
172    //   exception-specification, other declarations of the function shall
173    //   not specify an exception-specification.
174    if (getLangOpts().CPlusPlus11 &&
175        hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) {
176      Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch)
177        << hasImplicitExceptionSpec(Old);
178      if (!Old->getLocation().isInvalid())
179        Diag(Old->getLocation(), diag::note_previous_declaration);
180    }
181    return false;
182  }
183
184  // The failure was something other than an empty exception
185  // specification; return an error.
186  if (!MissingExceptionSpecification && !MissingEmptyExceptionSpecification)
187    return true;
188
189  const FunctionProtoType *NewProto =
190    New->getType()->getAs<FunctionProtoType>();
191
192  // The new function declaration is only missing an empty exception
193  // specification "throw()". If the throw() specification came from a
194  // function in a system header that has C linkage, just add an empty
195  // exception specification to the "new" declaration. This is an
196  // egregious workaround for glibc, which adds throw() specifications
197  // to many libc functions as an optimization. Unfortunately, that
198  // optimization isn't permitted by the C++ standard, so we're forced
199  // to work around it here.
200  if (MissingEmptyExceptionSpecification && NewProto &&
201      (Old->getLocation().isInvalid() ||
202       Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&
203      Old->isExternC()) {
204    FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
205    EPI.ExceptionSpecType = EST_DynamicNone;
206    QualType NewType =
207      Context.getFunctionType(NewProto->getResultType(),
208                              ArrayRef<QualType>(NewProto->arg_type_begin(),
209                                                 NewProto->getNumArgs()),
210                              EPI);
211    New->setType(NewType);
212    return false;
213  }
214
215  if (MissingExceptionSpecification && NewProto) {
216    const FunctionProtoType *OldProto =
217      Old->getType()->getAs<FunctionProtoType>();
218
219    FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
220    EPI.ExceptionSpecType = OldProto->getExceptionSpecType();
221    if (EPI.ExceptionSpecType == EST_Dynamic) {
222      EPI.NumExceptions = OldProto->getNumExceptions();
223      EPI.Exceptions = OldProto->exception_begin();
224    } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
225      // FIXME: We can't just take the expression from the old prototype. It
226      // likely contains references to the old prototype's parameters.
227    }
228
229    // Update the type of the function with the appropriate exception
230    // specification.
231    QualType NewType =
232      Context.getFunctionType(NewProto->getResultType(),
233                              ArrayRef<QualType>(NewProto->arg_type_begin(),
234                                                 NewProto->getNumArgs()),
235                              EPI);
236    New->setType(NewType);
237
238    // If exceptions are disabled, suppress the warning about missing
239    // exception specifications for new and delete operators.
240    if (!getLangOpts().CXXExceptions) {
241      switch (New->getDeclName().getCXXOverloadedOperator()) {
242      case OO_New:
243      case OO_Array_New:
244      case OO_Delete:
245      case OO_Array_Delete:
246        if (New->getDeclContext()->isTranslationUnit())
247          return false;
248        break;
249
250      default:
251        break;
252      }
253    }
254
255    // Warn about the lack of exception specification.
256    SmallString<128> ExceptionSpecString;
257    llvm::raw_svector_ostream OS(ExceptionSpecString);
258    switch (OldProto->getExceptionSpecType()) {
259    case EST_DynamicNone:
260      OS << "throw()";
261      break;
262
263    case EST_Dynamic: {
264      OS << "throw(";
265      bool OnFirstException = true;
266      for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(),
267                                              EEnd = OldProto->exception_end();
268           E != EEnd;
269           ++E) {
270        if (OnFirstException)
271          OnFirstException = false;
272        else
273          OS << ", ";
274
275        OS << E->getAsString(getPrintingPolicy());
276      }
277      OS << ")";
278      break;
279    }
280
281    case EST_BasicNoexcept:
282      OS << "noexcept";
283      break;
284
285    case EST_ComputedNoexcept:
286      OS << "noexcept(";
287      OldProto->getNoexceptExpr()->printPretty(OS, 0, getPrintingPolicy());
288      OS << ")";
289      break;
290
291    default:
292      llvm_unreachable("This spec type is compatible with none.");
293    }
294    OS.flush();
295
296    SourceLocation FixItLoc;
297    if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
298      TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
299      if (FunctionTypeLoc FTLoc = TL.getAs<FunctionTypeLoc>())
300        FixItLoc = PP.getLocForEndOfToken(FTLoc.getLocalRangeEnd());
301    }
302
303    if (FixItLoc.isInvalid())
304      Diag(New->getLocation(), diag::warn_missing_exception_specification)
305        << New << OS.str();
306    else {
307      // FIXME: This will get more complicated with C++0x
308      // late-specified return types.
309      Diag(New->getLocation(), diag::warn_missing_exception_specification)
310        << New << OS.str()
311        << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str());
312    }
313
314    if (!Old->getLocation().isInvalid())
315      Diag(Old->getLocation(), diag::note_previous_declaration);
316
317    return false;
318  }
319
320  Diag(New->getLocation(), DiagID);
321  Diag(Old->getLocation(), diag::note_previous_declaration);
322  return true;
323}
324
325/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
326/// exception specifications. Exception specifications are equivalent if
327/// they allow exactly the same set of exception types. It does not matter how
328/// that is achieved. See C++ [except.spec]p2.
329bool Sema::CheckEquivalentExceptionSpec(
330    const FunctionProtoType *Old, SourceLocation OldLoc,
331    const FunctionProtoType *New, SourceLocation NewLoc) {
332  unsigned DiagID = diag::err_mismatched_exception_spec;
333  if (getLangOpts().MicrosoftExt)
334    DiagID = diag::warn_mismatched_exception_spec;
335  return CheckEquivalentExceptionSpec(PDiag(DiagID),
336                                      PDiag(diag::note_previous_declaration),
337                                      Old, OldLoc, New, NewLoc);
338}
339
340/// CheckEquivalentExceptionSpec - Check if the two types have compatible
341/// exception specifications. See C++ [except.spec]p3.
342///
343/// \return \c false if the exception specifications match, \c true if there is
344/// a problem. If \c true is returned, either a diagnostic has already been
345/// produced or \c *MissingExceptionSpecification is set to \c true.
346bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
347                                        const PartialDiagnostic & NoteID,
348                                        const FunctionProtoType *Old,
349                                        SourceLocation OldLoc,
350                                        const FunctionProtoType *New,
351                                        SourceLocation NewLoc,
352                                        bool *MissingExceptionSpecification,
353                                        bool*MissingEmptyExceptionSpecification,
354                                        bool AllowNoexceptAllMatchWithNoSpec,
355                                        bool IsOperatorNew) {
356  // Just completely ignore this under -fno-exceptions.
357  if (!getLangOpts().CXXExceptions)
358    return false;
359
360  if (MissingExceptionSpecification)
361    *MissingExceptionSpecification = false;
362
363  if (MissingEmptyExceptionSpecification)
364    *MissingEmptyExceptionSpecification = false;
365
366  Old = ResolveExceptionSpec(NewLoc, Old);
367  if (!Old)
368    return false;
369  New = ResolveExceptionSpec(NewLoc, New);
370  if (!New)
371    return false;
372
373  // C++0x [except.spec]p3: Two exception-specifications are compatible if:
374  //   - both are non-throwing, regardless of their form,
375  //   - both have the form noexcept(constant-expression) and the constant-
376  //     expressions are equivalent,
377  //   - both are dynamic-exception-specifications that have the same set of
378  //     adjusted types.
379  //
380  // C++0x [except.spec]p12: An exception-specifcation is non-throwing if it is
381  //   of the form throw(), noexcept, or noexcept(constant-expression) where the
382  //   constant-expression yields true.
383  //
384  // C++0x [except.spec]p4: If any declaration of a function has an exception-
385  //   specifier that is not a noexcept-specification allowing all exceptions,
386  //   all declarations [...] of that function shall have a compatible
387  //   exception-specification.
388  //
389  // That last point basically means that noexcept(false) matches no spec.
390  // It's considered when AllowNoexceptAllMatchWithNoSpec is true.
391
392  ExceptionSpecificationType OldEST = Old->getExceptionSpecType();
393  ExceptionSpecificationType NewEST = New->getExceptionSpecType();
394
395  assert(!isUnresolvedExceptionSpec(OldEST) &&
396         !isUnresolvedExceptionSpec(NewEST) &&
397         "Shouldn't see unknown exception specifications here");
398
399  // Shortcut the case where both have no spec.
400  if (OldEST == EST_None && NewEST == EST_None)
401    return false;
402
403  FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(Context);
404  FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(Context);
405  if (OldNR == FunctionProtoType::NR_BadNoexcept ||
406      NewNR == FunctionProtoType::NR_BadNoexcept)
407    return false;
408
409  // Dependent noexcept specifiers are compatible with each other, but nothing
410  // else.
411  // One noexcept is compatible with another if the argument is the same
412  if (OldNR == NewNR &&
413      OldNR != FunctionProtoType::NR_NoNoexcept &&
414      NewNR != FunctionProtoType::NR_NoNoexcept)
415    return false;
416  if (OldNR != NewNR &&
417      OldNR != FunctionProtoType::NR_NoNoexcept &&
418      NewNR != FunctionProtoType::NR_NoNoexcept) {
419    Diag(NewLoc, DiagID);
420    if (NoteID.getDiagID() != 0)
421      Diag(OldLoc, NoteID);
422    return true;
423  }
424
425  // The MS extension throw(...) is compatible with itself.
426  if (OldEST == EST_MSAny && NewEST == EST_MSAny)
427    return false;
428
429  // It's also compatible with no spec.
430  if ((OldEST == EST_None && NewEST == EST_MSAny) ||
431      (OldEST == EST_MSAny && NewEST == EST_None))
432    return false;
433
434  // It's also compatible with noexcept(false).
435  if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw)
436    return false;
437  if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw)
438    return false;
439
440  // As described above, noexcept(false) matches no spec only for functions.
441  if (AllowNoexceptAllMatchWithNoSpec) {
442    if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw)
443      return false;
444    if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw)
445      return false;
446  }
447
448  // Any non-throwing specifications are compatible.
449  bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow ||
450                        OldEST == EST_DynamicNone;
451  bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow ||
452                        NewEST == EST_DynamicNone;
453  if (OldNonThrowing && NewNonThrowing)
454    return false;
455
456  // As a special compatibility feature, under C++0x we accept no spec and
457  // throw(std::bad_alloc) as equivalent for operator new and operator new[].
458  // This is because the implicit declaration changed, but old code would break.
459  if (getLangOpts().CPlusPlus11 && IsOperatorNew) {
460    const FunctionProtoType *WithExceptions = 0;
461    if (OldEST == EST_None && NewEST == EST_Dynamic)
462      WithExceptions = New;
463    else if (OldEST == EST_Dynamic && NewEST == EST_None)
464      WithExceptions = Old;
465    if (WithExceptions && WithExceptions->getNumExceptions() == 1) {
466      // One has no spec, the other throw(something). If that something is
467      // std::bad_alloc, all conditions are met.
468      QualType Exception = *WithExceptions->exception_begin();
469      if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) {
470        IdentifierInfo* Name = ExRecord->getIdentifier();
471        if (Name && Name->getName() == "bad_alloc") {
472          // It's called bad_alloc, but is it in std?
473          DeclContext* DC = ExRecord->getDeclContext();
474          DC = DC->getEnclosingNamespaceContext();
475          if (NamespaceDecl* NS = dyn_cast<NamespaceDecl>(DC)) {
476            IdentifierInfo* NSName = NS->getIdentifier();
477            DC = DC->getParent();
478            if (NSName && NSName->getName() == "std" &&
479                DC->getEnclosingNamespaceContext()->isTranslationUnit()) {
480              return false;
481            }
482          }
483        }
484      }
485    }
486  }
487
488  // At this point, the only remaining valid case is two matching dynamic
489  // specifications. We return here unless both specifications are dynamic.
490  if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) {
491    if (MissingExceptionSpecification && Old->hasExceptionSpec() &&
492        !New->hasExceptionSpec()) {
493      // The old type has an exception specification of some sort, but
494      // the new type does not.
495      *MissingExceptionSpecification = true;
496
497      if (MissingEmptyExceptionSpecification && OldNonThrowing) {
498        // The old type has a throw() or noexcept(true) exception specification
499        // and the new type has no exception specification, and the caller asked
500        // to handle this itself.
501        *MissingEmptyExceptionSpecification = true;
502      }
503
504      return true;
505    }
506
507    Diag(NewLoc, DiagID);
508    if (NoteID.getDiagID() != 0)
509      Diag(OldLoc, NoteID);
510    return true;
511  }
512
513  assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic &&
514      "Exception compatibility logic error: non-dynamic spec slipped through.");
515
516  bool Success = true;
517  // Both have a dynamic exception spec. Collect the first set, then compare
518  // to the second.
519  llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
520  for (FunctionProtoType::exception_iterator I = Old->exception_begin(),
521       E = Old->exception_end(); I != E; ++I)
522    OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType());
523
524  for (FunctionProtoType::exception_iterator I = New->exception_begin(),
525       E = New->exception_end(); I != E && Success; ++I) {
526    CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType();
527    if(OldTypes.count(TypePtr))
528      NewTypes.insert(TypePtr);
529    else
530      Success = false;
531  }
532
533  Success = Success && OldTypes.size() == NewTypes.size();
534
535  if (Success) {
536    return false;
537  }
538  Diag(NewLoc, DiagID);
539  if (NoteID.getDiagID() != 0)
540    Diag(OldLoc, NoteID);
541  return true;
542}
543
544/// CheckExceptionSpecSubset - Check whether the second function type's
545/// exception specification is a subset (or equivalent) of the first function
546/// type. This is used by override and pointer assignment checks.
547bool Sema::CheckExceptionSpecSubset(
548    const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
549    const FunctionProtoType *Superset, SourceLocation SuperLoc,
550    const FunctionProtoType *Subset, SourceLocation SubLoc) {
551
552  // Just auto-succeed under -fno-exceptions.
553  if (!getLangOpts().CXXExceptions)
554    return false;
555
556  // FIXME: As usual, we could be more specific in our error messages, but
557  // that better waits until we've got types with source locations.
558
559  if (!SubLoc.isValid())
560    SubLoc = SuperLoc;
561
562  // Resolve the exception specifications, if needed.
563  Superset = ResolveExceptionSpec(SuperLoc, Superset);
564  if (!Superset)
565    return false;
566  Subset = ResolveExceptionSpec(SubLoc, Subset);
567  if (!Subset)
568    return false;
569
570  ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType();
571
572  // If superset contains everything, we're done.
573  if (SuperEST == EST_None || SuperEST == EST_MSAny)
574    return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
575
576  // If there are dependent noexcept specs, assume everything is fine. Unlike
577  // with the equivalency check, this is safe in this case, because we don't
578  // want to merge declarations. Checks after instantiation will catch any
579  // omissions we make here.
580  // We also shortcut checking if a noexcept expression was bad.
581
582  FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context);
583  if (SuperNR == FunctionProtoType::NR_BadNoexcept ||
584      SuperNR == FunctionProtoType::NR_Dependent)
585    return false;
586
587  // Another case of the superset containing everything.
588  if (SuperNR == FunctionProtoType::NR_Throw)
589    return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
590
591  ExceptionSpecificationType SubEST = Subset->getExceptionSpecType();
592
593  assert(!isUnresolvedExceptionSpec(SuperEST) &&
594         !isUnresolvedExceptionSpec(SubEST) &&
595         "Shouldn't see unknown exception specifications here");
596
597  // It does not. If the subset contains everything, we've failed.
598  if (SubEST == EST_None || SubEST == EST_MSAny) {
599    Diag(SubLoc, DiagID);
600    if (NoteID.getDiagID() != 0)
601      Diag(SuperLoc, NoteID);
602    return true;
603  }
604
605  FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context);
606  if (SubNR == FunctionProtoType::NR_BadNoexcept ||
607      SubNR == FunctionProtoType::NR_Dependent)
608    return false;
609
610  // Another case of the subset containing everything.
611  if (SubNR == FunctionProtoType::NR_Throw) {
612    Diag(SubLoc, DiagID);
613    if (NoteID.getDiagID() != 0)
614      Diag(SuperLoc, NoteID);
615    return true;
616  }
617
618  // If the subset contains nothing, we're done.
619  if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow)
620    return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
621
622  // Otherwise, if the superset contains nothing, we've failed.
623  if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) {
624    Diag(SubLoc, DiagID);
625    if (NoteID.getDiagID() != 0)
626      Diag(SuperLoc, NoteID);
627    return true;
628  }
629
630  assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic &&
631         "Exception spec subset: non-dynamic case slipped through.");
632
633  // Neither contains everything or nothing. Do a proper comparison.
634  for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(),
635       SubE = Subset->exception_end(); SubI != SubE; ++SubI) {
636    // Take one type from the subset.
637    QualType CanonicalSubT = Context.getCanonicalType(*SubI);
638    // Unwrap pointers and references so that we can do checks within a class
639    // hierarchy. Don't unwrap member pointers; they don't have hierarchy
640    // conversions on the pointee.
641    bool SubIsPointer = false;
642    if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
643      CanonicalSubT = RefTy->getPointeeType();
644    if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) {
645      CanonicalSubT = PtrTy->getPointeeType();
646      SubIsPointer = true;
647    }
648    bool SubIsClass = CanonicalSubT->isRecordType();
649    CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
650
651    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
652                       /*DetectVirtual=*/false);
653
654    bool Contained = false;
655    // Make sure it's in the superset.
656    for (FunctionProtoType::exception_iterator SuperI =
657           Superset->exception_begin(), SuperE = Superset->exception_end();
658         SuperI != SuperE; ++SuperI) {
659      QualType CanonicalSuperT = Context.getCanonicalType(*SuperI);
660      // SubT must be SuperT or derived from it, or pointer or reference to
661      // such types.
662      if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
663        CanonicalSuperT = RefTy->getPointeeType();
664      if (SubIsPointer) {
665        if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>())
666          CanonicalSuperT = PtrTy->getPointeeType();
667        else {
668          continue;
669        }
670      }
671      CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
672      // If the types are the same, move on to the next type in the subset.
673      if (CanonicalSubT == CanonicalSuperT) {
674        Contained = true;
675        break;
676      }
677
678      // Otherwise we need to check the inheritance.
679      if (!SubIsClass || !CanonicalSuperT->isRecordType())
680        continue;
681
682      Paths.clear();
683      if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths))
684        continue;
685
686      if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT)))
687        continue;
688
689      // Do this check from a context without privileges.
690      switch (CheckBaseClassAccess(SourceLocation(),
691                                   CanonicalSuperT, CanonicalSubT,
692                                   Paths.front(),
693                                   /*Diagnostic*/ 0,
694                                   /*ForceCheck*/ true,
695                                   /*ForceUnprivileged*/ true)) {
696      case AR_accessible: break;
697      case AR_inaccessible: continue;
698      case AR_dependent:
699        llvm_unreachable("access check dependent for unprivileged context");
700      case AR_delayed:
701        llvm_unreachable("access check delayed in non-declaration");
702      }
703
704      Contained = true;
705      break;
706    }
707    if (!Contained) {
708      Diag(SubLoc, DiagID);
709      if (NoteID.getDiagID() != 0)
710        Diag(SuperLoc, NoteID);
711      return true;
712    }
713  }
714  // We've run half the gauntlet.
715  return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
716}
717
718static bool CheckSpecForTypesEquivalent(Sema &S,
719    const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
720    QualType Target, SourceLocation TargetLoc,
721    QualType Source, SourceLocation SourceLoc)
722{
723  const FunctionProtoType *TFunc = GetUnderlyingFunction(Target);
724  if (!TFunc)
725    return false;
726  const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
727  if (!SFunc)
728    return false;
729
730  return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
731                                        SFunc, SourceLoc);
732}
733
734/// CheckParamExceptionSpec - Check if the parameter and return types of the
735/// two functions have equivalent exception specs. This is part of the
736/// assignment and override compatibility check. We do not check the parameters
737/// of parameter function pointers recursively, as no sane programmer would
738/// even be able to write such a function type.
739bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
740    const FunctionProtoType *Target, SourceLocation TargetLoc,
741    const FunctionProtoType *Source, SourceLocation SourceLoc)
742{
743  if (CheckSpecForTypesEquivalent(*this,
744                           PDiag(diag::err_deep_exception_specs_differ) << 0,
745                                  PDiag(),
746                                  Target->getResultType(), TargetLoc,
747                                  Source->getResultType(), SourceLoc))
748    return true;
749
750  // We shouldn't even be testing this unless the arguments are otherwise
751  // compatible.
752  assert(Target->getNumArgs() == Source->getNumArgs() &&
753         "Functions have different argument counts.");
754  for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) {
755    if (CheckSpecForTypesEquivalent(*this,
756                           PDiag(diag::err_deep_exception_specs_differ) << 1,
757                                    PDiag(),
758                                    Target->getArgType(i), TargetLoc,
759                                    Source->getArgType(i), SourceLoc))
760      return true;
761  }
762  return false;
763}
764
765bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
766{
767  // First we check for applicability.
768  // Target type must be a function, function pointer or function reference.
769  const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
770  if (!ToFunc)
771    return false;
772
773  // SourceType must be a function or function pointer.
774  const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
775  if (!FromFunc)
776    return false;
777
778  // Now we've got the correct types on both sides, check their compatibility.
779  // This means that the source of the conversion can only throw a subset of
780  // the exceptions of the target, and any exception specs on arguments or
781  // return types must be equivalent.
782  return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),
783                                  PDiag(), ToFunc,
784                                  From->getSourceRange().getBegin(),
785                                  FromFunc, SourceLocation());
786}
787
788bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
789                                                const CXXMethodDecl *Old) {
790  if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) {
791    // Don't check uninstantiated template destructors at all. We can only
792    // synthesize correct specs after the template is instantiated.
793    if (New->getParent()->isDependentType())
794      return false;
795    if (New->getParent()->isBeingDefined()) {
796      // The destructor might be updated once the definition is finished. So
797      // remember it and check later.
798      DelayedDestructorExceptionSpecChecks.push_back(std::make_pair(
799        cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old)));
800      return false;
801    }
802  }
803  unsigned DiagID = diag::err_override_exception_spec;
804  if (getLangOpts().MicrosoftExt)
805    DiagID = diag::warn_override_exception_spec;
806  return CheckExceptionSpecSubset(PDiag(DiagID),
807                                  PDiag(diag::note_overridden_virtual_function),
808                                  Old->getType()->getAs<FunctionProtoType>(),
809                                  Old->getLocation(),
810                                  New->getType()->getAs<FunctionProtoType>(),
811                                  New->getLocation());
812}
813
814static CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) {
815  Expr *E = const_cast<Expr*>(CE);
816  CanThrowResult R = CT_Cannot;
817  for (Expr::child_range I = E->children(); I && R != CT_Can; ++I)
818    R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I)));
819  return R;
820}
821
822static CanThrowResult canCalleeThrow(Sema &S, const Expr *E,
823                                           const Decl *D,
824                                           bool NullThrows = true) {
825  if (!D)
826    return NullThrows ? CT_Can : CT_Cannot;
827
828  // See if we can get a function type from the decl somehow.
829  const ValueDecl *VD = dyn_cast<ValueDecl>(D);
830  if (!VD) // If we have no clue what we're calling, assume the worst.
831    return CT_Can;
832
833  // As an extension, we assume that __attribute__((nothrow)) functions don't
834  // throw.
835  if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
836    return CT_Cannot;
837
838  QualType T = VD->getType();
839  const FunctionProtoType *FT;
840  if ((FT = T->getAs<FunctionProtoType>())) {
841  } else if (const PointerType *PT = T->getAs<PointerType>())
842    FT = PT->getPointeeType()->getAs<FunctionProtoType>();
843  else if (const ReferenceType *RT = T->getAs<ReferenceType>())
844    FT = RT->getPointeeType()->getAs<FunctionProtoType>();
845  else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
846    FT = MT->getPointeeType()->getAs<FunctionProtoType>();
847  else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
848    FT = BT->getPointeeType()->getAs<FunctionProtoType>();
849
850  if (!FT)
851    return CT_Can;
852
853  FT = S.ResolveExceptionSpec(E->getLocStart(), FT);
854  if (!FT)
855    return CT_Can;
856
857  return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
858}
859
860static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) {
861  if (DC->isTypeDependent())
862    return CT_Dependent;
863
864  if (!DC->getTypeAsWritten()->isReferenceType())
865    return CT_Cannot;
866
867  if (DC->getSubExpr()->isTypeDependent())
868    return CT_Dependent;
869
870  return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot;
871}
872
873static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) {
874  if (DC->isTypeOperand())
875    return CT_Cannot;
876
877  Expr *Op = DC->getExprOperand();
878  if (Op->isTypeDependent())
879    return CT_Dependent;
880
881  const RecordType *RT = Op->getType()->getAs<RecordType>();
882  if (!RT)
883    return CT_Cannot;
884
885  if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
886    return CT_Cannot;
887
888  if (Op->Classify(S.Context).isPRValue())
889    return CT_Cannot;
890
891  return CT_Can;
892}
893
894CanThrowResult Sema::canThrow(const Expr *E) {
895  // C++ [expr.unary.noexcept]p3:
896  //   [Can throw] if in a potentially-evaluated context the expression would
897  //   contain:
898  switch (E->getStmtClass()) {
899  case Expr::CXXThrowExprClass:
900    //   - a potentially evaluated throw-expression
901    return CT_Can;
902
903  case Expr::CXXDynamicCastExprClass: {
904    //   - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
905    //     where T is a reference type, that requires a run-time check
906    CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E));
907    if (CT == CT_Can)
908      return CT;
909    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
910  }
911
912  case Expr::CXXTypeidExprClass:
913    //   - a potentially evaluated typeid expression applied to a glvalue
914    //     expression whose type is a polymorphic class type
915    return canTypeidThrow(*this, cast<CXXTypeidExpr>(E));
916
917    //   - a potentially evaluated call to a function, member function, function
918    //     pointer, or member function pointer that does not have a non-throwing
919    //     exception-specification
920  case Expr::CallExprClass:
921  case Expr::CXXMemberCallExprClass:
922  case Expr::CXXOperatorCallExprClass:
923  case Expr::UserDefinedLiteralClass: {
924    const CallExpr *CE = cast<CallExpr>(E);
925    CanThrowResult CT;
926    if (E->isTypeDependent())
927      CT = CT_Dependent;
928    else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
929      CT = CT_Cannot;
930    else
931      CT = canCalleeThrow(*this, E, CE->getCalleeDecl());
932    if (CT == CT_Can)
933      return CT;
934    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
935  }
936
937  case Expr::CXXConstructExprClass:
938  case Expr::CXXTemporaryObjectExprClass: {
939    CanThrowResult CT = canCalleeThrow(*this, E,
940        cast<CXXConstructExpr>(E)->getConstructor());
941    if (CT == CT_Can)
942      return CT;
943    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
944  }
945
946  case Expr::LambdaExprClass: {
947    const LambdaExpr *Lambda = cast<LambdaExpr>(E);
948    CanThrowResult CT = CT_Cannot;
949    for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(),
950                                        CapEnd = Lambda->capture_init_end();
951         Cap != CapEnd; ++Cap)
952      CT = mergeCanThrow(CT, canThrow(*Cap));
953    return CT;
954  }
955
956  case Expr::CXXNewExprClass: {
957    CanThrowResult CT;
958    if (E->isTypeDependent())
959      CT = CT_Dependent;
960    else
961      CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew());
962    if (CT == CT_Can)
963      return CT;
964    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
965  }
966
967  case Expr::CXXDeleteExprClass: {
968    CanThrowResult CT;
969    QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType();
970    if (DTy.isNull() || DTy->isDependentType()) {
971      CT = CT_Dependent;
972    } else {
973      CT = canCalleeThrow(*this, E,
974                          cast<CXXDeleteExpr>(E)->getOperatorDelete());
975      if (const RecordType *RT = DTy->getAs<RecordType>()) {
976        const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
977        CT = mergeCanThrow(CT, canCalleeThrow(*this, E, RD->getDestructor()));
978      }
979      if (CT == CT_Can)
980        return CT;
981    }
982    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
983  }
984
985  case Expr::CXXBindTemporaryExprClass: {
986    // The bound temporary has to be destroyed again, which might throw.
987    CanThrowResult CT = canCalleeThrow(*this, E,
988      cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor());
989    if (CT == CT_Can)
990      return CT;
991    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
992  }
993
994    // ObjC message sends are like function calls, but never have exception
995    // specs.
996  case Expr::ObjCMessageExprClass:
997  case Expr::ObjCPropertyRefExprClass:
998  case Expr::ObjCSubscriptRefExprClass:
999    return CT_Can;
1000
1001    // All the ObjC literals that are implemented as calls are
1002    // potentially throwing unless we decide to close off that
1003    // possibility.
1004  case Expr::ObjCArrayLiteralClass:
1005  case Expr::ObjCDictionaryLiteralClass:
1006  case Expr::ObjCBoxedExprClass:
1007    return CT_Can;
1008
1009    // Many other things have subexpressions, so we have to test those.
1010    // Some are simple:
1011  case Expr::ConditionalOperatorClass:
1012  case Expr::CompoundLiteralExprClass:
1013  case Expr::CXXConstCastExprClass:
1014  case Expr::CXXReinterpretCastExprClass:
1015  case Expr::DesignatedInitExprClass:
1016  case Expr::ExprWithCleanupsClass:
1017  case Expr::ExtVectorElementExprClass:
1018  case Expr::InitListExprClass:
1019  case Expr::MemberExprClass:
1020  case Expr::ObjCIsaExprClass:
1021  case Expr::ObjCIvarRefExprClass:
1022  case Expr::ParenExprClass:
1023  case Expr::ParenListExprClass:
1024  case Expr::ShuffleVectorExprClass:
1025  case Expr::VAArgExprClass:
1026    return canSubExprsThrow(*this, E);
1027
1028    // Some might be dependent for other reasons.
1029  case Expr::ArraySubscriptExprClass:
1030  case Expr::BinaryOperatorClass:
1031  case Expr::CompoundAssignOperatorClass:
1032  case Expr::CStyleCastExprClass:
1033  case Expr::CXXStaticCastExprClass:
1034  case Expr::CXXFunctionalCastExprClass:
1035  case Expr::ImplicitCastExprClass:
1036  case Expr::MaterializeTemporaryExprClass:
1037  case Expr::UnaryOperatorClass: {
1038    CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot;
1039    return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1040  }
1041
1042    // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms.
1043  case Expr::StmtExprClass:
1044    return CT_Can;
1045
1046  case Expr::CXXDefaultArgExprClass:
1047    return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr());
1048
1049  case Expr::CXXDefaultInitExprClass:
1050    return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr());
1051
1052  case Expr::ChooseExprClass:
1053    if (E->isTypeDependent() || E->isValueDependent())
1054      return CT_Dependent;
1055    return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr(Context));
1056
1057  case Expr::GenericSelectionExprClass:
1058    if (cast<GenericSelectionExpr>(E)->isResultDependent())
1059      return CT_Dependent;
1060    return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr());
1061
1062    // Some expressions are always dependent.
1063  case Expr::CXXDependentScopeMemberExprClass:
1064  case Expr::CXXUnresolvedConstructExprClass:
1065  case Expr::DependentScopeDeclRefExprClass:
1066    return CT_Dependent;
1067
1068  case Expr::AsTypeExprClass:
1069  case Expr::BinaryConditionalOperatorClass:
1070  case Expr::BlockExprClass:
1071  case Expr::CUDAKernelCallExprClass:
1072  case Expr::DeclRefExprClass:
1073  case Expr::ObjCBridgedCastExprClass:
1074  case Expr::ObjCIndirectCopyRestoreExprClass:
1075  case Expr::ObjCProtocolExprClass:
1076  case Expr::ObjCSelectorExprClass:
1077  case Expr::OffsetOfExprClass:
1078  case Expr::PackExpansionExprClass:
1079  case Expr::PseudoObjectExprClass:
1080  case Expr::SubstNonTypeTemplateParmExprClass:
1081  case Expr::SubstNonTypeTemplateParmPackExprClass:
1082  case Expr::FunctionParmPackExprClass:
1083  case Expr::UnaryExprOrTypeTraitExprClass:
1084  case Expr::UnresolvedLookupExprClass:
1085  case Expr::UnresolvedMemberExprClass:
1086    // FIXME: Can any of the above throw?  If so, when?
1087    return CT_Cannot;
1088
1089  case Expr::AddrLabelExprClass:
1090  case Expr::ArrayTypeTraitExprClass:
1091  case Expr::AtomicExprClass:
1092  case Expr::BinaryTypeTraitExprClass:
1093  case Expr::TypeTraitExprClass:
1094  case Expr::CXXBoolLiteralExprClass:
1095  case Expr::CXXNoexceptExprClass:
1096  case Expr::CXXNullPtrLiteralExprClass:
1097  case Expr::CXXPseudoDestructorExprClass:
1098  case Expr::CXXScalarValueInitExprClass:
1099  case Expr::CXXThisExprClass:
1100  case Expr::CXXUuidofExprClass:
1101  case Expr::CharacterLiteralClass:
1102  case Expr::ExpressionTraitExprClass:
1103  case Expr::FloatingLiteralClass:
1104  case Expr::GNUNullExprClass:
1105  case Expr::ImaginaryLiteralClass:
1106  case Expr::ImplicitValueInitExprClass:
1107  case Expr::IntegerLiteralClass:
1108  case Expr::ObjCEncodeExprClass:
1109  case Expr::ObjCStringLiteralClass:
1110  case Expr::ObjCBoolLiteralExprClass:
1111  case Expr::OpaqueValueExprClass:
1112  case Expr::PredefinedExprClass:
1113  case Expr::SizeOfPackExprClass:
1114  case Expr::StringLiteralClass:
1115  case Expr::UnaryTypeTraitExprClass:
1116    // These expressions can never throw.
1117    return CT_Cannot;
1118
1119  case Expr::MSPropertyRefExprClass:
1120    llvm_unreachable("Invalid class for expression");
1121
1122#define STMT(CLASS, PARENT) case Expr::CLASS##Class:
1123#define STMT_RANGE(Base, First, Last)
1124#define LAST_STMT_RANGE(BASE, FIRST, LAST)
1125#define EXPR(CLASS, PARENT)
1126#define ABSTRACT_STMT(STMT)
1127#include "clang/AST/StmtNodes.inc"
1128  case Expr::NoStmtClass:
1129    llvm_unreachable("Invalid class for expression");
1130  }
1131  llvm_unreachable("Bogus StmtClass");
1132}
1133
1134} // end namespace clang
1135