From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/test/CXX/basic/basic.def.odr/p1-var.cpp | 21 + clang/test/CXX/basic/basic.def.odr/p2-typeid.cpp | 36 ++ clang/test/CXX/basic/basic.link/p9.cpp | 10 + .../basic.lookup.argdep/p2-template-id.cpp | 27 + .../basic/basic.lookup/basic.lookup.argdep/p2.cpp | 110 ++++ .../basic/basic.lookup/basic.lookup.argdep/p3.cpp | 20 + .../basic/basic.lookup/basic.lookup.argdep/p4.cpp | 64 +++ .../basic.lookup/basic.lookup.classref/p1.cpp | 89 +++ .../basic.lookup/basic.lookup.classref/p3.cpp | 30 ++ .../basic/basic.lookup/basic.lookup.elab/p2.cpp | 60 +++ .../basic.lookup/basic.lookup.elab/templateid.cpp | 18 + .../basic.lookup.qual/class.qual/p2.cpp | 27 + .../basic.lookup.qual/namespace.qual/p2.cpp | 65 +++ .../basic.lookup.qual/namespace.qual/p3.cpp | 41 ++ .../basic.lookup.qual/namespace.qual/p4.cpp | 25 + .../basic.lookup.qual/namespace.qual/p5.cpp | 35 ++ .../basic/basic.lookup/basic.lookup.qual/p6-0x.cpp | 26 + .../basic/basic.lookup/basic.lookup.qual/p6.cpp | 24 + .../basic/basic.lookup/basic.lookup.udir/p1.cpp | 35 ++ .../basic/basic.lookup/basic.lookup.unqual/p11.cpp | 12 + .../basic/basic.lookup/basic.lookup.unqual/p12.cpp | 13 + .../basic/basic.lookup/basic.lookup.unqual/p13.cpp | 8 + .../basic/basic.lookup/basic.lookup.unqual/p14.cpp | 18 + .../basic/basic.lookup/basic.lookup.unqual/p15.cpp | 17 + .../basic/basic.lookup/basic.lookup.unqual/p3.cpp | 24 + .../basic/basic.lookup/basic.lookup.unqual/p7.cpp | 37 ++ .../basic/basic.scope/basic.scope.hiding/p2.cpp | 24 + .../basic/basic.scope/basic.scope.local/p4-0x.cpp | 68 +++ .../CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp | 26 + .../CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp | 18 + .../CXX/basic/basic.start/basic.start.main/p2a.cpp | 8 + .../CXX/basic/basic.start/basic.start.main/p2b.cpp | 8 + .../CXX/basic/basic.start/basic.start.main/p2c.cpp | 4 + .../CXX/basic/basic.start/basic.start.main/p2d.cpp | 4 + .../CXX/basic/basic.start/basic.start.main/p2e.cpp | 4 + .../CXX/basic/basic.start/basic.start.main/p2f.cpp | 7 + .../CXX/basic/basic.start/basic.start.main/p2g.cpp | 4 + .../CXX/basic/basic.start/basic.start.main/p2h.cpp | 5 + .../CXX/basic/basic.start/basic.start.main/p2i.cpp | 6 + .../basic.stc.dynamic.allocation/p1.cpp | 44 ++ .../basic.stc.dynamic.deallocation/p1.cpp | 11 + .../basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp | 7 + .../basic.stc.dynamic/p2-noexceptions.cpp | 13 + .../CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp | 28 + clang/test/CXX/basic/basic.types/p10.cpp | 132 +++++ .../test/CXX/class.access/class.access.base/p1.cpp | 155 ++++++ .../test/CXX/class.access/class.access.base/p5.cpp | 75 +++ .../test/CXX/class.access/class.access.dcl/p1.cpp | 199 +++++++ .../test/CXX/class.access/class.access.nest/p1.cpp | 33 ++ clang/test/CXX/class.access/class.friend/p1.cpp | 356 ++++++++++++ clang/test/CXX/class.access/class.friend/p11.cpp | 19 + .../CXX/class.access/class.friend/p2-cxx03.cpp | 13 + .../CXX/class.access/class.friend/p3-cxx0x.cpp | 29 + clang/test/CXX/class.access/class.friend/p6.cpp | 20 + .../CXX/class.access/class.protected/p1-cxx11.cpp | 20 + clang/test/CXX/class.access/class.protected/p1.cpp | 519 ++++++++++++++++++ clang/test/CXX/class.access/p4.cpp | 510 ++++++++++++++++++ clang/test/CXX/class.access/p6.cpp | 192 +++++++ clang/test/CXX/class.derived/class.abstract/p4.cpp | 80 +++ clang/test/CXX/class.derived/class.abstract/p5.cpp | 23 + .../CXX/class.derived/class.member.lookup/p6.cpp | 40 ++ .../CXX/class.derived/class.member.lookup/p8.cpp | 63 +++ .../CXX/class.derived/class.member.lookup/p9.cpp | 28 + clang/test/CXX/class.derived/class.virtual/p12.cpp | 19 + clang/test/CXX/class.derived/class.virtual/p2.cpp | 37 ++ .../test/CXX/class.derived/class.virtual/p3-0x.cpp | 53 ++ clang/test/CXX/class.derived/p1.cpp | 40 ++ clang/test/CXX/class.derived/p2.cpp | 8 + .../CXX/class/class.base/class.base.init/p5-0x.cpp | 26 + clang/test/CXX/class/class.bit/p2.cpp | 22 + clang/test/CXX/class/class.friend/p1-ambiguous.cpp | 37 ++ clang/test/CXX/class/class.friend/p1-cxx11.cpp | 12 + clang/test/CXX/class/class.friend/p1.cpp | 77 +++ clang/test/CXX/class/class.friend/p2.cpp | 10 + clang/test/CXX/class/class.friend/p6.cpp | 10 + clang/test/CXX/class/class.local/p1-0x.cpp | 18 + clang/test/CXX/class/class.local/p1.cpp | 18 + clang/test/CXX/class/class.local/p2.cpp | 11 + clang/test/CXX/class/class.local/p3.cpp | 30 ++ clang/test/CXX/class/class.local/p4.cpp | 10 + clang/test/CXX/class/class.mem/p1.cpp | 91 ++++ clang/test/CXX/class/class.mem/p13.cpp | 40 ++ clang/test/CXX/class/class.mem/p14.cpp | 19 + clang/test/CXX/class/class.mem/p1b.cpp | 46 ++ clang/test/CXX/class/class.mem/p2.cpp | 58 ++ clang/test/CXX/class/class.mem/p5-0x.cpp | 9 + clang/test/CXX/class/class.mem/p8-0x.cpp | 53 ++ .../class/class.mfct/class.mfct.non-static/p3.cpp | 98 ++++ clang/test/CXX/class/class.nest/p1-cxx0x.cpp | 14 + clang/test/CXX/class/class.nest/p1.cpp | 14 + clang/test/CXX/class/class.nest/p3.cpp | 25 + clang/test/CXX/class/class.nested.type/p1.cpp | 13 + .../class/class.static/class.static.data/p3.cpp | 44 ++ .../class/class.static/class.static.data/p4.cpp | 25 + clang/test/CXX/class/class.union/p1.cpp | 125 +++++ clang/test/CXX/class/class.union/p2-0x.cpp | 48 ++ clang/test/CXX/class/p1-0x.cpp | 6 + clang/test/CXX/class/p2-0x.cpp | 28 + clang/test/CXX/class/p6-0x.cpp | 30 ++ clang/test/CXX/conv/conv.mem/p4.cpp | 65 +++ clang/test/CXX/conv/conv.prom/p2.cpp | 16 + clang/test/CXX/conv/conv.prom/p4.cpp | 9 + clang/test/CXX/conv/conv.ptr/p2.cpp | 6 + clang/test/CXX/conv/conv.qual/pr6089.cpp | 18 + .../namespace.def/namespace.memdef/p3.cpp | 93 ++++ .../namespace.def/namespace.unnamed/p1.cpp | 42 ++ .../dcl.dcl/basic.namespace/namespace.def/p1.cpp | 9 + .../dcl.dcl/basic.namespace/namespace.def/p2.cpp | 24 + .../dcl.dcl/basic.namespace/namespace.def/p7.cpp | 13 + .../dcl.dcl/basic.namespace/namespace.def/p8.cpp | 118 ++++ .../dcl.dcl/basic.namespace/namespace.udecl/p1.cpp | 110 ++++ .../basic.namespace/namespace.udecl/p10.cpp | 34 ++ .../basic.namespace/namespace.udecl/p11.cpp | 91 ++++ .../basic.namespace/namespace.udecl/p12.cpp | 163 ++++++ .../basic.namespace/namespace.udecl/p13.cpp | 76 +++ .../basic.namespace/namespace.udecl/p3-cxx0x.cpp | 46 ++ .../dcl.dcl/basic.namespace/namespace.udecl/p4.cpp | 213 ++++++++ .../basic.namespace/namespace.udecl/p5-cxx0x.cpp | 12 + .../basic.namespace/namespace.udecl/p6-cxx0x.cpp | 8 + .../basic.namespace/namespace.udecl/p8-cxx0x.cpp | 15 + .../dcl.dcl/basic.namespace/namespace.udecl/p8.cpp | 98 ++++ .../dcl.dcl/basic.namespace/namespace.udir/p1.cpp | 141 +++++ .../dcl.dcl/basic.namespace/namespace.udir/p6.cpp | 15 + .../CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp | 13 + clang/test/CXX/dcl.dcl/dcl.enum/p5.cpp | 56 ++ clang/test/CXX/dcl.dcl/dcl.link/p7.cpp | 30 ++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 123 +++++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp | 26 + .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 139 +++++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp | 249 +++++++++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp | 112 ++++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp | 68 +++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp | 38 ++ .../test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp | 37 ++ .../test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp | 13 + .../test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp | 7 + .../test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp | 16 + clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp | 32 ++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp | 14 + clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp | 26 + clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp | 11 + .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp | 49 ++ .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp | 51 ++ .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp | 43 ++ .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp | 68 +++ .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp | 104 ++++ .../dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp | 32 ++ .../dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp | 19 + .../dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp | 61 +++ .../dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp | 27 + .../dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp | 108 ++++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp | 43 ++ .../CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp | 160 ++++++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp | 8 + clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp | 15 + clang/test/CXX/dcl.dcl/p4-0x.cpp | 21 + .../dcl.fct.def/dcl.fct.def.default/p2.cpp | 56 ++ .../CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp | 78 +++ .../CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp | 18 + .../CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp | 17 + .../dcl.init/dcl.init.list/p7-0x-fixits.cpp | 33 ++ .../CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp | 209 ++++++++ .../dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp | 210 ++++++++ .../CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp | 19 + .../test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp | 14 + .../test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp | 3 + .../CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp | 194 +++++++ .../dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp | 77 +++ .../dcl.init.ref/p5-cxx0x-no-extra-copy.cpp | 64 +++ .../dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp | 53 ++ .../CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp | 135 +++++ .../test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp | 40 ++ .../CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp | 19 + .../CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp | 2 + clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp | 44 ++ clang/test/CXX/dcl.decl/dcl.init/p5.cpp | 20 + clang/test/CXX/dcl.decl/dcl.init/p6.cpp | 28 + .../dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp | 7 + .../test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp | 54 ++ .../dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp | 16 + .../dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp | 9 + .../dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp | 13 + .../dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp | 55 ++ .../dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp | 19 + .../dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp | 33 ++ .../dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp | 7 + .../dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp | 4 + .../dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp | 62 +++ .../test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp | 48 ++ .../test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp | 31 ++ .../CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp | 7 + clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp | 3 + .../CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp | 53 ++ clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp | 20 + .../CXX/dcl.decl/dcl.meaning/dcl.fct/p8-0x.cpp | 6 + clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp | 10 + .../CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp | 3 + .../test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp | 26 + clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp | 145 +++++ .../CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp | 26 + clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp | 24 + clang/test/CXX/dcl.decl/dcl.meaning/p1.cpp | 37 ++ clang/test/CXX/dcl.decl/dcl.name/p1.cpp | 20 + clang/test/CXX/dcl.decl/p4-0x.cpp | 8 + clang/test/CXX/except/except.handle/p16.cpp | 40 ++ clang/test/CXX/except/except.spec/canonical.cpp | 53 ++ clang/test/CXX/except/except.spec/p1.cpp | 81 +++ clang/test/CXX/except/except.spec/p11.cpp | 12 + clang/test/CXX/except/except.spec/p14-ir.cpp | 79 +++ clang/test/CXX/except/except.spec/p14.cpp | 41 ++ clang/test/CXX/except/except.spec/p15.cpp | 24 + .../CXX/except/except.spec/p2-dynamic-types.cpp | 34 ++ clang/test/CXX/except/except.spec/p2-places.cpp | 63 +++ clang/test/CXX/except/except.spec/p3.cpp | 106 ++++ clang/test/CXX/except/except.spec/p5-pointers.cpp | 85 +++ clang/test/CXX/except/except.spec/p5-virtual.cpp | 96 ++++ clang/test/CXX/except/except.spec/p9-dynamic.cpp | 12 + clang/test/CXX/except/except.spec/p9-noexcept.cpp | 19 + clang/test/CXX/except/except.spec/template.cpp | 12 + clang/test/CXX/expr/expr.ass/p9-cxx11.cpp | 34 ++ clang/test/CXX/expr/expr.cast/p4-0x.cpp | 11 + clang/test/CXX/expr/expr.cast/p4.cpp | 23 + clang/test/CXX/expr/expr.const/p2-0x.cpp | 596 +++++++++++++++++++++ clang/test/CXX/expr/expr.const/p3-0x-nowarn.cpp | 8 + clang/test/CXX/expr/expr.const/p3-0x.cpp | 110 ++++ clang/test/CXX/expr/expr.const/p5-0x.cpp | 85 +++ clang/test/CXX/expr/expr.mptr.oper/p5.cpp | 61 +++ clang/test/CXX/expr/expr.mptr.oper/p6-0x.cpp | 34 ++ clang/test/CXX/expr/expr.post/expr.call/p7-0x.cpp | 30 ++ .../CXX/expr/expr.post/expr.const.cast/p1-0x.cpp | 17 + .../CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp | 14 + clang/test/CXX/expr/expr.post/expr.ref/p3.cpp | 15 + .../expr/expr.post/expr.reinterpret.cast/p1-0x.cpp | 16 + .../CXX/expr/expr.post/expr.static.cast/p3-0x.cpp | 24 + .../CXX/expr/expr.post/expr.static.cast/p9-0x.cpp | 29 + .../CXX/expr/expr.post/expr.type.conv/p1-0x.cpp | 12 + .../expr/expr.prim/expr.prim.general/p12-0x.cpp | 38 ++ .../CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp | 101 ++++ .../CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp | 20 + .../CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp | 78 +++ .../CXX/expr/expr.prim/expr.prim.lambda/blocks.mm | 88 +++ .../expr.prim.lambda/default-arguments.cpp | 50 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p10.cpp | 40 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p11.cpp | 16 + .../CXX/expr/expr.prim/expr.prim.lambda/p12.cpp | 77 +++ .../CXX/expr/expr.prim/expr.prim.lambda/p13.cpp | 16 + .../CXX/expr/expr.prim/expr.prim.lambda/p14.cpp | 75 +++ .../CXX/expr/expr.prim/expr.prim.lambda/p15.cpp | 12 + .../CXX/expr/expr.prim/expr.prim.lambda/p16.cpp | 40 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p18.cpp | 45 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p19.cpp | 28 + .../CXX/expr/expr.prim/expr.prim.lambda/p2.cpp | 42 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p20.cpp | 12 + .../CXX/expr/expr.prim/expr.prim.lambda/p21.cpp | 9 + .../CXX/expr/expr.prim/expr.prim.lambda/p23.cpp | 58 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p3.cpp | 6 + .../CXX/expr/expr.prim/expr.prim.lambda/p4.cpp | 51 ++ .../test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm | 8 + .../CXX/expr/expr.prim/expr.prim.lambda/p5.cpp | 64 +++ .../CXX/expr/expr.prim/expr.prim.lambda/p6.cpp | 22 + .../CXX/expr/expr.prim/expr.prim.lambda/p7.cpp | 56 ++ .../CXX/expr/expr.prim/expr.prim.lambda/p8.cpp | 29 + .../expr/expr.prim/expr.prim.lambda/templates.cpp | 149 ++++++ clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp | 46 ++ .../CXX/expr/expr.unary/expr.new/p17-crash.cpp | 14 + clang/test/CXX/expr/expr.unary/expr.new/p17.cpp | 16 + clang/test/CXX/expr/expr.unary/expr.new/p19.cpp | 46 ++ .../test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp | 23 + clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp | 13 + clang/test/CXX/expr/expr.unary/expr.new/p20.cpp | 141 +++++ .../test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp | 38 ++ .../CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp | 26 + .../expr/expr.unary/expr.unary.noexcept/sema.cpp | 189 +++++++ .../CXX/expr/expr.unary/expr.unary.noexcept/ser.h | 8 + .../test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 28 + .../test/CXX/expr/expr.unary/expr.unary.op/p4.cpp | 43 ++ .../test/CXX/expr/expr.unary/expr.unary.op/p6.cpp | 35 ++ clang/test/CXX/expr/p3.cpp | 15 + clang/test/CXX/expr/p8.cpp | 18 + clang/test/CXX/expr/p9.cpp | 50 ++ clang/test/CXX/lex/lex.charset/p2-cxx11.cpp | 42 ++ clang/test/CXX/lex/lex.charset/p2-cxx98.cpp | 55 ++ clang/test/CXX/lex/lex.literal/lex.ccon/p1.cpp | 16 + clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp | 7 + clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp | 14 + clang/test/CXX/lex/lex.literal/lex.ext/p2.cpp | 16 + clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp | 18 + clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp | 18 + clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp | 13 + clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp | 14 + clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp | 27 + clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp | 18 + clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp | 13 + clang/test/CXX/lex/lex.pptoken/p3-0x.cpp | 11 + clang/test/CXX/lex/lex.trigraph/p1.cpp | 19 + clang/test/CXX/lex/lex.trigraph/p2.cpp | 3 + clang/test/CXX/lex/lex.trigraph/p3.cpp | 8 + clang/test/CXX/over/over.built/p1.cpp | 16 + clang/test/CXX/over/over.built/p23.cpp | 25 + clang/test/CXX/over/over.built/p25.cpp | 15 + clang/test/CXX/over/over.load/p2-0x.cpp | 24 + .../over.best.ics/over.ics.list/p6.cpp | 15 + .../over.best.ics/over.ics.user/p3-0x.cpp | 14 + .../over.match.best/over.ics.rank/p3-0x.cpp | 59 ++ .../CXX/over/over.match/over.match.best/p1.cpp | 16 + .../over.match.funcs/over.match.copy/p1.cpp | 37 ++ .../CXX/over/over.match/over.match.funcs/p4-0x.cpp | 70 +++ clang/test/CXX/over/over.oper/over.literal/p2.cpp | 35 ++ clang/test/CXX/over/over.oper/over.literal/p3.cpp | 40 ++ clang/test/CXX/over/over.oper/over.literal/p5.cpp | 22 + clang/test/CXX/over/over.oper/over.literal/p6.cpp | 13 + clang/test/CXX/over/over.oper/over.literal/p7.cpp | 16 + clang/test/CXX/over/over.oper/over.literal/p8.cpp | 19 + clang/test/CXX/over/over.over/p1.cpp | 94 ++++ .../over.over/p2-resolve-single-template-id.cpp | 191 +++++++ clang/test/CXX/over/over.over/p2.cpp | 9 + clang/test/CXX/over/over.over/p4.cpp | 20 + .../CXX/special/class.copy/implicit-move-def.cpp | 117 ++++ .../test/CXX/special/class.copy/implicit-move.cpp | 236 ++++++++ clang/test/CXX/special/class.copy/p11.0x.copy.cpp | 121 +++++ clang/test/CXX/special/class.copy/p11.0x.move.cpp | 164 ++++++ clang/test/CXX/special/class.copy/p13-0x.cpp | 60 +++ clang/test/CXX/special/class.copy/p15-0x.cpp | 41 ++ clang/test/CXX/special/class.copy/p15-inclass.cpp | 42 ++ clang/test/CXX/special/class.copy/p20.cpp | 46 ++ clang/test/CXX/special/class.copy/p3.cpp | 27 + clang/test/CXX/special/class.copy/p33-0x.cpp | 57 ++ clang/test/CXX/special/class.copy/p8-cxx11.cpp | 48 ++ clang/test/CXX/special/class.copy/p9.cpp | 44 ++ clang/test/CXX/special/class.ctor/p1.cpp | 42 ++ clang/test/CXX/special/class.ctor/p4-0x.cpp | 7 + clang/test/CXX/special/class.ctor/p5-0x.cpp | 182 +++++++ clang/test/CXX/special/class.ctor/p6-0x.cpp | 57 ++ clang/test/CXX/special/class.dtor/p10-0x.cpp | 39 ++ clang/test/CXX/special/class.dtor/p2-0x.cpp | 10 + clang/test/CXX/special/class.dtor/p2.cpp | 7 + clang/test/CXX/special/class.dtor/p3-0x.cpp | 177 ++++++ clang/test/CXX/special/class.dtor/p5-0x.cpp | 104 ++++ clang/test/CXX/special/class.dtor/p9.cpp | 85 +++ clang/test/CXX/special/class.free/p1.cpp | 11 + clang/test/CXX/special/class.free/p6.cpp | 11 + clang/test/CXX/special/class.inhctor/elsewhere.cpp | 57 ++ clang/test/CXX/special/class.inhctor/p3.cpp | 48 ++ clang/test/CXX/special/class.inhctor/p7.cpp | 29 + .../special/class.init/class.base.init/p8-0x.cpp | 62 +++ .../special/class.init/class.base.init/p9-0x.cpp | 36 ++ clang/test/CXX/special/class.temporary/p1.cpp | 57 ++ clang/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp | 40 ++ clang/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp | 55 ++ clang/test/CXX/stmt.stmt/stmt.dcl/p3.cpp | 47 ++ .../CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp | 209 ++++++++ clang/test/CXX/stmt.stmt/stmt.label/p1.cpp | 25 + clang/test/CXX/stmt.stmt/stmt.select/p3.cpp | 19 + .../stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp | 39 ++ clang/test/CXX/temp/p3.cpp | 18 + .../CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp | 60 +++ .../test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp | 95 ++++ .../test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp | 205 +++++++ .../CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp | 40 ++ .../CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp | 20 + clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp | 42 ++ clang/test/CXX/temp/temp.decls/p3.cpp | 7 + clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp | 8 + clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp | 45 ++ clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp | 13 + .../CXX/temp/temp.decls/temp.class.spec/p6.cpp | 76 +++ .../CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp | 8 + .../CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp | 13 + .../CXX/temp/temp.decls/temp.class.spec/p9.cpp | 26 + .../temp.class.spec/temp.class.order/p2.cpp | 48 ++ .../temp.class.spec.mfunc/p1-neg.cpp | 25 + .../temp.class.spec/temp.class.spec.mfunc/p1.cpp | 25 + .../temp.decls/temp.class/temp.mem.class/p1.cpp | 27 + .../temp.decls/temp.class/temp.mem.enum/p1.cpp | 152 ++++++ .../temp.class/temp.mem.func/p1-retmem.cpp | 28 + .../temp.decls/temp.class/temp.mem.func/p1.cpp | 100 ++++ .../temp.decls/temp.class/temp.mem.func/p1inst.cpp | 17 + .../temp.decls/temp.class/temp.mem.func/pr5056.cpp | 17 + .../temp.decls/temp.class/temp.static/p1-inst.cpp | 28 + .../temp/temp.decls/temp.class/temp.static/p1.cpp | 26 + .../temp.decls/temp.fct/temp.func.order/p3-0x.cpp | 17 + .../temp.decls/temp.fct/temp.func.order/p3.cpp | 16 + .../temp.decls/temp.fct/temp.func.order/p4.cpp | 23 + .../temp.decls/temp.fct/temp.func.order/p5.cpp | 12 + .../temp.decls/temp.fct/temp.over.link/p4-neg.cpp | 27 + .../temp/temp.decls/temp.fct/temp.over.link/p4.cpp | 13 + .../temp/temp.decls/temp.fct/temp.over.link/p6.cpp | 16 + clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp | 358 +++++++++++++ clang/test/CXX/temp/temp.decls/temp.friend/p3.cpp | 12 + clang/test/CXX/temp/temp.decls/temp.friend/p4.cpp | 28 + clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp | 103 ++++ clang/test/CXX/temp/temp.decls/temp.friend/p8.cpp | 6 + clang/test/CXX/temp/temp.decls/temp.mem/p1.cpp | 35 ++ clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp | 6 + clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp | 79 +++ .../temp/temp.decls/temp.variadic/deduction.cpp | 50 ++ .../temp/temp.decls/temp.variadic/example-bind.cpp | 352 ++++++++++++ .../temp.decls/temp.variadic/example-function.cpp | 86 +++ .../temp.decls/temp.variadic/example-tuple.cpp | 260 +++++++++ .../temp/temp.decls/temp.variadic/ext-blocks.cpp | 46 ++ .../temp.decls/temp.variadic/fixed-expansion.cpp | 127 +++++ .../temp.variadic/injected-class-name.cpp | 75 +++ .../temp.decls/temp.variadic/metafunctions.cpp | 274 ++++++++++ .../temp.variadic/multi-level-substitution.cpp | 251 +++++++++ .../test/CXX/temp/temp.decls/temp.variadic/p1.cpp | 9 + .../test/CXX/temp/temp.decls/temp.variadic/p2.cpp | 22 + .../test/CXX/temp/temp.decls/temp.variadic/p4.cpp | 193 +++++++ .../test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 403 ++++++++++++++ .../temp.variadic/parameter-matching.cpp | 43 ++ .../temp.decls/temp.variadic/partial-ordering.cpp | 61 +++ .../temp/temp.fct.spec/temp.arg.explicit/p1.cpp | 12 + .../temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp | 27 + .../temp.arg.explicit/p3-nodeduct.cpp | 36 ++ .../temp/temp.fct.spec/temp.arg.explicit/p3.cpp | 65 +++ .../temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp | 68 +++ .../CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp | 41 ++ .../test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp | 26 + .../temp/temp.fct.spec/temp.deduct/sfinae-1.cpp | 42 ++ .../temp.deduct/temp.deduct.call/basic.cpp | 30 ++ .../temp.deduct/temp.deduct.call/p1-0x.cpp | 88 +++ .../temp.deduct/temp.deduct.call/p2.cpp | 31 ++ .../temp.deduct/temp.deduct.call/p3-0x.cpp | 46 ++ .../temp.deduct/temp.deduct.call/p3.cpp | 148 +++++ .../temp.deduct/temp.deduct.call/p4.cpp | 20 + .../temp.deduct/temp.deduct.call/p6.cpp | 128 +++++ .../temp.deduct/temp.deduct.conv/p2.cpp | 36 ++ .../temp.deduct/temp.deduct.conv/p3.cpp | 30 ++ .../temp.deduct/temp.deduct.conv/p4.cpp | 44 ++ .../temp.deduct/temp.deduct.funcaddr/p1.cpp | 22 + .../temp.deduct/temp.deduct.partial/p11.cpp | 47 ++ .../temp.deduct/temp.deduct.partial/p12.cpp | 27 + .../temp.deduct/temp.deduct.partial/p9-0x.cpp | 10 + .../temp.deduct/temp.deduct.type/p10-0x.cpp | 4 + .../temp.deduct/temp.deduct.type/p17.cpp | 31 ++ .../temp.deduct/temp.deduct.type/p2-0x.cpp | 23 + .../temp.deduct/temp.deduct.type/p21.cpp | 31 ++ .../temp.deduct/temp.deduct.type/p22.cpp | 14 + .../temp.deduct/temp.deduct.type/p5-0x.cpp | 22 + .../temp.deduct/temp.deduct.type/p8-0x.cpp | 47 ++ .../temp.deduct/temp.deduct.type/p9-0x.cpp | 55 ++ clang/test/CXX/temp/temp.names/p2.cpp | 13 + clang/test/CXX/temp/temp.names/p4.cpp | 15 + clang/test/CXX/temp/temp.param/p1.cpp | 12 + clang/test/CXX/temp/temp.param/p10-0x.cpp | 13 + clang/test/CXX/temp/temp.param/p10.cpp | 12 + clang/test/CXX/temp/temp.param/p11-0x.cpp | 81 +++ clang/test/CXX/temp/temp.param/p11.cpp | 15 + clang/test/CXX/temp/temp.param/p12.cpp | 39 ++ clang/test/CXX/temp/temp.param/p13.cpp | 14 + clang/test/CXX/temp/temp.param/p14.cpp | 5 + clang/test/CXX/temp/temp.param/p15-cxx0x.cpp | 24 + clang/test/CXX/temp/temp.param/p15.cpp | 12 + clang/test/CXX/temp/temp.param/p2.cpp | 22 + clang/test/CXX/temp/temp.param/p3.cpp | 40 ++ clang/test/CXX/temp/temp.param/p4.cpp | 21 + clang/test/CXX/temp/temp.param/p5.cpp | 13 + clang/test/CXX/temp/temp.param/p7.cpp | 15 + clang/test/CXX/temp/temp.param/p8.cpp | 6 + clang/test/CXX/temp/temp.param/p9-0x.cpp | 61 +++ clang/test/CXX/temp/temp.param/p9.cpp | 23 + .../temp/temp.res/temp.dep.res/temp.point/p1.cpp | 32 ++ clang/test/CXX/temp/temp.res/temp.dep/p3.cpp | 43 ++ .../temp.res/temp.dep/temp.dep.constexpr/p2-0x.cpp | 27 + .../temp.res/temp.dep/temp.dep.constexpr/p2.cpp | 21 + .../temp/temp.res/temp.dep/temp.dep.type/p1.cpp | 30 ++ clang/test/CXX/temp/temp.res/temp.local/p1.cpp | 32 ++ clang/test/CXX/temp/temp.res/temp.local/p3.cpp | 32 ++ clang/test/CXX/temp/temp.res/temp.local/p7.cpp | 10 + clang/test/CXX/temp/temp.res/temp.local/p8.cpp | 53 ++ clang/test/CXX/temp/temp.res/temp.local/p9.cpp | 15 + clang/test/CXX/temp/temp.spec/p5.cpp | 47 ++ .../CXX/temp/temp.spec/temp.expl.spec/examples.cpp | 334 ++++++++++++ .../test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp | 99 ++++ .../test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp | 7 + .../test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp | 8 + .../test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp | 6 + .../test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp | 42 ++ .../test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp | 33 ++ .../test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp | 38 ++ .../test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp | 34 ++ .../test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp | 20 + .../test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp | 30 ++ .../CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp | 302 +++++++++++ .../test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp | 252 +++++++++ .../test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp | 14 + .../test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp | 30 ++ .../test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp | 13 + .../test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp | 58 ++ .../temp/temp.spec/temp.expl.spec/p5-example.cpp | 34 ++ .../test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp | 61 +++ .../test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp | 63 +++ .../test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp | 14 + .../CXX/temp/temp.spec/temp.explicit/p1-0x.cpp | 24 + .../CXX/temp/temp.spec/temp.explicit/p1-emit.cpp | 29 + clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp | 89 +++ .../test/CXX/temp/temp.spec/temp.explicit/p10.cpp | 33 ++ .../test/CXX/temp/temp.spec/temp.explicit/p11.cpp | 18 + .../test/CXX/temp/temp.spec/temp.explicit/p12.cpp | 6 + clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp | 43 ++ .../CXX/temp/temp.spec/temp.explicit/p3-0x.cpp | 65 +++ clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp | 81 +++ clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp | 48 ++ clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp | 17 + clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp | 35 ++ clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp | 36 ++ clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp | 40 ++ .../temp/temp.spec/temp.explicit/p9-linkage.cpp | 66 +++ clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp | 59 ++ clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp | 104 ++++ clang/test/CXX/temp/temp.spec/temp.inst/p11.cpp | 15 + clang/test/CXX/temp/temp.type/p1-0x.cpp | 23 + 511 files changed, 26163 insertions(+) create mode 100644 clang/test/CXX/basic/basic.def.odr/p1-var.cpp create mode 100644 clang/test/CXX/basic/basic.def.odr/p2-typeid.cpp create mode 100644 clang/test/CXX/basic/basic.link/p9.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp create mode 100644 clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp create mode 100644 clang/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp create mode 100644 clang/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp create mode 100644 clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp create mode 100644 clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2a.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2b.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2c.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2d.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2e.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2f.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2g.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2h.cpp create mode 100644 clang/test/CXX/basic/basic.start/basic.start.main/p2i.cpp create mode 100644 clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp create mode 100644 clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp create mode 100644 clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp create mode 100644 clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp create mode 100644 clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp create mode 100644 clang/test/CXX/basic/basic.types/p10.cpp create mode 100644 clang/test/CXX/class.access/class.access.base/p1.cpp create mode 100644 clang/test/CXX/class.access/class.access.base/p5.cpp create mode 100644 clang/test/CXX/class.access/class.access.dcl/p1.cpp create mode 100644 clang/test/CXX/class.access/class.access.nest/p1.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p1.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p11.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p2-cxx03.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p6.cpp create mode 100644 clang/test/CXX/class.access/class.protected/p1-cxx11.cpp create mode 100644 clang/test/CXX/class.access/class.protected/p1.cpp create mode 100644 clang/test/CXX/class.access/p4.cpp create mode 100644 clang/test/CXX/class.access/p6.cpp create mode 100644 clang/test/CXX/class.derived/class.abstract/p4.cpp create mode 100644 clang/test/CXX/class.derived/class.abstract/p5.cpp create mode 100644 clang/test/CXX/class.derived/class.member.lookup/p6.cpp create mode 100644 clang/test/CXX/class.derived/class.member.lookup/p8.cpp create mode 100644 clang/test/CXX/class.derived/class.member.lookup/p9.cpp create mode 100644 clang/test/CXX/class.derived/class.virtual/p12.cpp create mode 100644 clang/test/CXX/class.derived/class.virtual/p2.cpp create mode 100644 clang/test/CXX/class.derived/class.virtual/p3-0x.cpp create mode 100644 clang/test/CXX/class.derived/p1.cpp create mode 100644 clang/test/CXX/class.derived/p2.cpp create mode 100644 clang/test/CXX/class/class.base/class.base.init/p5-0x.cpp create mode 100644 clang/test/CXX/class/class.bit/p2.cpp create mode 100644 clang/test/CXX/class/class.friend/p1-ambiguous.cpp create mode 100644 clang/test/CXX/class/class.friend/p1-cxx11.cpp create mode 100644 clang/test/CXX/class/class.friend/p1.cpp create mode 100644 clang/test/CXX/class/class.friend/p2.cpp create mode 100644 clang/test/CXX/class/class.friend/p6.cpp create mode 100644 clang/test/CXX/class/class.local/p1-0x.cpp create mode 100644 clang/test/CXX/class/class.local/p1.cpp create mode 100644 clang/test/CXX/class/class.local/p2.cpp create mode 100644 clang/test/CXX/class/class.local/p3.cpp create mode 100644 clang/test/CXX/class/class.local/p4.cpp create mode 100644 clang/test/CXX/class/class.mem/p1.cpp create mode 100644 clang/test/CXX/class/class.mem/p13.cpp create mode 100644 clang/test/CXX/class/class.mem/p14.cpp create mode 100644 clang/test/CXX/class/class.mem/p1b.cpp create mode 100644 clang/test/CXX/class/class.mem/p2.cpp create mode 100644 clang/test/CXX/class/class.mem/p5-0x.cpp create mode 100644 clang/test/CXX/class/class.mem/p8-0x.cpp create mode 100644 clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp create mode 100644 clang/test/CXX/class/class.nest/p1-cxx0x.cpp create mode 100644 clang/test/CXX/class/class.nest/p1.cpp create mode 100644 clang/test/CXX/class/class.nest/p3.cpp create mode 100644 clang/test/CXX/class/class.nested.type/p1.cpp create mode 100644 clang/test/CXX/class/class.static/class.static.data/p3.cpp create mode 100644 clang/test/CXX/class/class.static/class.static.data/p4.cpp create mode 100644 clang/test/CXX/class/class.union/p1.cpp create mode 100644 clang/test/CXX/class/class.union/p2-0x.cpp create mode 100644 clang/test/CXX/class/p1-0x.cpp create mode 100644 clang/test/CXX/class/p2-0x.cpp create mode 100644 clang/test/CXX/class/p6-0x.cpp create mode 100644 clang/test/CXX/conv/conv.mem/p4.cpp create mode 100644 clang/test/CXX/conv/conv.prom/p2.cpp create mode 100644 clang/test/CXX/conv/conv.prom/p4.cpp create mode 100644 clang/test/CXX/conv/conv.ptr/p2.cpp create mode 100644 clang/test/CXX/conv/conv.qual/pr6089.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp create mode 100644 clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.enum/p5.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.link/p7.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp create mode 100644 clang/test/CXX/dcl.dcl/p4-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/p5.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/p6.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.name/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/p4-0x.cpp create mode 100644 clang/test/CXX/except/except.handle/p16.cpp create mode 100644 clang/test/CXX/except/except.spec/canonical.cpp create mode 100644 clang/test/CXX/except/except.spec/p1.cpp create mode 100644 clang/test/CXX/except/except.spec/p11.cpp create mode 100644 clang/test/CXX/except/except.spec/p14-ir.cpp create mode 100644 clang/test/CXX/except/except.spec/p14.cpp create mode 100644 clang/test/CXX/except/except.spec/p15.cpp create mode 100644 clang/test/CXX/except/except.spec/p2-dynamic-types.cpp create mode 100644 clang/test/CXX/except/except.spec/p2-places.cpp create mode 100644 clang/test/CXX/except/except.spec/p3.cpp create mode 100644 clang/test/CXX/except/except.spec/p5-pointers.cpp create mode 100644 clang/test/CXX/except/except.spec/p5-virtual.cpp create mode 100644 clang/test/CXX/except/except.spec/p9-dynamic.cpp create mode 100644 clang/test/CXX/except/except.spec/p9-noexcept.cpp create mode 100644 clang/test/CXX/except/except.spec/template.cpp create mode 100644 clang/test/CXX/expr/expr.ass/p9-cxx11.cpp create mode 100644 clang/test/CXX/expr/expr.cast/p4-0x.cpp create mode 100644 clang/test/CXX/expr/expr.cast/p4.cpp create mode 100644 clang/test/CXX/expr/expr.const/p2-0x.cpp create mode 100644 clang/test/CXX/expr/expr.const/p3-0x-nowarn.cpp create mode 100644 clang/test/CXX/expr/expr.const/p3-0x.cpp create mode 100644 clang/test/CXX/expr/expr.const/p5-0x.cpp create mode 100644 clang/test/CXX/expr/expr.mptr.oper/p5.cpp create mode 100644 clang/test/CXX/expr/expr.mptr.oper/p6-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.call/p7-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.ref/p3.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp create mode 100644 clang/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p20.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp create mode 100644 clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.new/p17.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.new/p19.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.new/p20.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp create mode 100644 clang/test/CXX/expr/p3.cpp create mode 100644 clang/test/CXX/expr/p8.cpp create mode 100644 clang/test/CXX/expr/p9.cpp create mode 100644 clang/test/CXX/lex/lex.charset/p2-cxx11.cpp create mode 100644 clang/test/CXX/lex/lex.charset/p2-cxx98.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ccon/p1.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p2.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp create mode 100644 clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp create mode 100644 clang/test/CXX/lex/lex.pptoken/p3-0x.cpp create mode 100644 clang/test/CXX/lex/lex.trigraph/p1.cpp create mode 100644 clang/test/CXX/lex/lex.trigraph/p2.cpp create mode 100644 clang/test/CXX/lex/lex.trigraph/p3.cpp create mode 100644 clang/test/CXX/over/over.built/p1.cpp create mode 100644 clang/test/CXX/over/over.built/p23.cpp create mode 100644 clang/test/CXX/over/over.built/p25.cpp create mode 100644 clang/test/CXX/over/over.load/p2-0x.cpp create mode 100644 clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.list/p6.cpp create mode 100644 clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp create mode 100644 clang/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp create mode 100644 clang/test/CXX/over/over.match/over.match.best/p1.cpp create mode 100644 clang/test/CXX/over/over.match/over.match.funcs/over.match.copy/p1.cpp create mode 100644 clang/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp create mode 100644 clang/test/CXX/over/over.oper/over.literal/p2.cpp create mode 100644 clang/test/CXX/over/over.oper/over.literal/p3.cpp create mode 100644 clang/test/CXX/over/over.oper/over.literal/p5.cpp create mode 100644 clang/test/CXX/over/over.oper/over.literal/p6.cpp create mode 100644 clang/test/CXX/over/over.oper/over.literal/p7.cpp create mode 100644 clang/test/CXX/over/over.oper/over.literal/p8.cpp create mode 100644 clang/test/CXX/over/over.over/p1.cpp create mode 100644 clang/test/CXX/over/over.over/p2-resolve-single-template-id.cpp create mode 100644 clang/test/CXX/over/over.over/p2.cpp create mode 100644 clang/test/CXX/over/over.over/p4.cpp create mode 100644 clang/test/CXX/special/class.copy/implicit-move-def.cpp create mode 100644 clang/test/CXX/special/class.copy/implicit-move.cpp create mode 100644 clang/test/CXX/special/class.copy/p11.0x.copy.cpp create mode 100644 clang/test/CXX/special/class.copy/p11.0x.move.cpp create mode 100644 clang/test/CXX/special/class.copy/p13-0x.cpp create mode 100644 clang/test/CXX/special/class.copy/p15-0x.cpp create mode 100644 clang/test/CXX/special/class.copy/p15-inclass.cpp create mode 100644 clang/test/CXX/special/class.copy/p20.cpp create mode 100644 clang/test/CXX/special/class.copy/p3.cpp create mode 100644 clang/test/CXX/special/class.copy/p33-0x.cpp create mode 100644 clang/test/CXX/special/class.copy/p8-cxx11.cpp create mode 100644 clang/test/CXX/special/class.copy/p9.cpp create mode 100644 clang/test/CXX/special/class.ctor/p1.cpp create mode 100644 clang/test/CXX/special/class.ctor/p4-0x.cpp create mode 100644 clang/test/CXX/special/class.ctor/p5-0x.cpp create mode 100644 clang/test/CXX/special/class.ctor/p6-0x.cpp create mode 100644 clang/test/CXX/special/class.dtor/p10-0x.cpp create mode 100644 clang/test/CXX/special/class.dtor/p2-0x.cpp create mode 100644 clang/test/CXX/special/class.dtor/p2.cpp create mode 100644 clang/test/CXX/special/class.dtor/p3-0x.cpp create mode 100644 clang/test/CXX/special/class.dtor/p5-0x.cpp create mode 100644 clang/test/CXX/special/class.dtor/p9.cpp create mode 100644 clang/test/CXX/special/class.free/p1.cpp create mode 100644 clang/test/CXX/special/class.free/p6.cpp create mode 100644 clang/test/CXX/special/class.inhctor/elsewhere.cpp create mode 100644 clang/test/CXX/special/class.inhctor/p3.cpp create mode 100644 clang/test/CXX/special/class.inhctor/p7.cpp create mode 100644 clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp create mode 100644 clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp create mode 100644 clang/test/CXX/special/class.temporary/p1.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.dcl/p3.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.label/p1.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.select/p3.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp create mode 100644 clang/test/CXX/temp/p3.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp create mode 100644 clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp create mode 100644 clang/test/CXX/temp/temp.decls/p3.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.friend/p3.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.friend/p4.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.friend/p8.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.mem/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/p2.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.names/p2.cpp create mode 100644 clang/test/CXX/temp/temp.names/p4.cpp create mode 100644 clang/test/CXX/temp/temp.param/p1.cpp create mode 100644 clang/test/CXX/temp/temp.param/p10-0x.cpp create mode 100644 clang/test/CXX/temp/temp.param/p10.cpp create mode 100644 clang/test/CXX/temp/temp.param/p11-0x.cpp create mode 100644 clang/test/CXX/temp/temp.param/p11.cpp create mode 100644 clang/test/CXX/temp/temp.param/p12.cpp create mode 100644 clang/test/CXX/temp/temp.param/p13.cpp create mode 100644 clang/test/CXX/temp/temp.param/p14.cpp create mode 100644 clang/test/CXX/temp/temp.param/p15-cxx0x.cpp create mode 100644 clang/test/CXX/temp/temp.param/p15.cpp create mode 100644 clang/test/CXX/temp/temp.param/p2.cpp create mode 100644 clang/test/CXX/temp/temp.param/p3.cpp create mode 100644 clang/test/CXX/temp/temp.param/p4.cpp create mode 100644 clang/test/CXX/temp/temp.param/p5.cpp create mode 100644 clang/test/CXX/temp/temp.param/p7.cpp create mode 100644 clang/test/CXX/temp/temp.param/p8.cpp create mode 100644 clang/test/CXX/temp/temp.param/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.param/p9.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.dep/p3.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2-0x.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.local/p1.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.local/p3.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.local/p7.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.local/p8.cpp create mode 100644 clang/test/CXX/temp/temp.res/temp.local/p9.cpp create mode 100644 clang/test/CXX/temp/temp.spec/p5.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.inst/p11.cpp create mode 100644 clang/test/CXX/temp/temp.type/p1-0x.cpp (limited to 'clang/test/CXX') diff --git a/clang/test/CXX/basic/basic.def.odr/p1-var.cpp b/clang/test/CXX/basic/basic.def.odr/p1-var.cpp new file mode 100644 index 0000000..892f546 --- /dev/null +++ b/clang/test/CXX/basic/basic.def.odr/p1-var.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++ [basic.def.odr]p1: +// No translation unit shall contain more than one definition of any +// variable, [...]. + +// Bad: in C++, these are both definitions. None of that C99 tentative stuff. +int i; // expected-note {{previous}} +int i; // expected-error {{redefinition}} + +// OK: decl + def +extern int j; +int j; + +// OK: def + decl +int k; +extern int k; + +// Bad. The important thing here is that we don't emit the diagnostic twice. +int l = 1; // expected-note {{previous}} +int l = 2; // expected-error {{redefinition}} diff --git a/clang/test/CXX/basic/basic.def.odr/p2-typeid.cpp b/clang/test/CXX/basic/basic.def.odr/p2-typeid.cpp new file mode 100644 index 0000000..55debe3 --- /dev/null +++ b/clang/test/CXX/basic/basic.def.odr/p2-typeid.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++ [basic.def.odr]p2: +// An expression is potentially evaluated unless it [...] is the +// operand of the typeid operator and the expression does not +// designate an lvalue of polymorphic class type. + +// FIXME: This should really include , but we don't have that yet. +namespace std { + class type_info; +} + +struct Poly { + virtual ~Poly(); +}; + +struct NonPoly { }; + +template +struct X { + Result f(T t) { return t + t; } // expected-error{{invalid operands}} + + void g(T t) { + (void)typeid(f(t)); // expected-note{{here}} + } +}; + +void test(X xp, X xpr, X xnp, X xnpr) { + // These are okay (although GCC and EDG get them wrong). + xp.g(Poly()); + xnp.g(NonPoly()); + xnpr.g(NonPoly()); + + // Triggers an error (as it should); + xpr.g(Poly()); // expected-note{{instantiation of member function}} +} diff --git a/clang/test/CXX/basic/basic.link/p9.cpp b/clang/test/CXX/basic/basic.link/p9.cpp new file mode 100644 index 0000000..680c93d --- /dev/null +++ b/clang/test/CXX/basic/basic.link/p9.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: This test is woefully incomplete. +namespace N { } // expected-note{{here}} + +// First bullet: two names with external linkage that refer to +// different kinds of entities. +void f() { + int N(); // expected-error{{redefinition}} expected-warning{{interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}} +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp new file mode 100644 index 0000000..f650ad5 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace N1 { + struct X { }; + int& f(void*); +} + +namespace N2 { + template struct Y { }; +} + +namespace N3 { + void test() { + int &ir = f((N2::Y*)0); + } +} + +int g(void *); +long g(N1::X); + +namespace N1 { + void h(int (*)(void *)); +} + +void test() { + h((&g)); +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp new file mode 100644 index 0000000..f5ad68b --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace N { + struct X { }; + + X operator+(X, X); + + void f(X); + void g(X); // expected-note{{candidate function}} + + void test_multiadd(X x) { + (void)(x + x); + } +} + +namespace M { + struct Y : N::X { }; +} + +void f(); // expected-note 2 {{'f' declared here}} + +void test_operator_adl(N::X x, M::Y y) { + (void)(x + x); + (void)(y + y); +} + +void test_func_adl(N::X x, M::Y y) { + f(x); + f(y); + (f)(x); // expected-error{{too many arguments to function call}} + ::f(x); // expected-error{{too many arguments to function call}} +} + +namespace N { + void test_multiadd2(X x) { + (void)(x + x); + } +} + + +void test_func_adl_only(N::X x) { + g(x); +} + +namespace M { + int g(N::X); // expected-note{{candidate function}} + + void test(N::X x) { + g(x); // expected-error{{call to 'g' is ambiguous}} + int i = (g)(x); + + int g(N::X); + g(x); // okay; calls locally-declared function, no ADL + } +} + + +void test_operator_name_adl(N::X x) { + (void)operator+(x, x); +} + +struct Z { }; +int& f(Z); + +namespace O { + char &f(); + void test_global_scope_adl(Z z) { + { + int& ir = f(z); + } + } +} + +extern "C" { + struct L { }; +} + +void h(L); // expected-note{{candidate function}} + +namespace P { + void h(L); // expected-note{{candidate function}} + void test_transparent_context_adl(L l) { + { + h(l); // expected-error {{call to 'h' is ambiguous}} + } + } +} + +namespace test5 { + namespace NS { + struct A; + void foo(void (*)(A&)); + } + void bar(NS::A& a); + + void test() { + foo(&bar); + } +} + +// PR6762: __builtin_va_list should be invisible to ADL on all platforms. +void test6_function(__builtin_va_list &argv); +namespace test6 { + void test6_function(__builtin_va_list &argv); + + void test() { + __builtin_va_list args; + test6_function(args); + } +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp new file mode 100644 index 0000000..c4c2c8d --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: embellish + +namespace test0 { + namespace A { + class Foo { + }; + + void foo(const Foo &foo); + } + + class Test { + enum E { foo = 0 }; + + void test() { + foo(A::Foo()); // expected-error {{not a function}} + } + }; +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp new file mode 100644 index 0000000..32dd75a --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace A { + class A { + friend void func(A); + friend A operator+(A,A); + }; +} + +namespace B { + class B { + static void func(B); + }; + B operator+(B,B); +} + +namespace D { + class D {}; +} + +namespace C { + class C {}; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'B::B' to 'const C::C &' for 1st argument}} + void func(C); // expected-note {{'C::func' declared here}} \ + // expected-note {{passing argument to parameter here}} + C operator+(C,C); + D::D operator+(D::D,D::D); +} + +namespace D { + using namespace C; +} + +namespace Test { + void test() { + func(A::A()); + // FIXME: namespace-aware typo correction causes an extra, misleading + // message in this case; some form of backtracking, diagnostic message + // delaying, or argument checking before emitting diagnostics is needed to + // avoid accepting and printing out a typo correction that proves to be + // incorrect once argument-dependent lookup resolution has occurred. + func(B::B()); // expected-error {{use of undeclared identifier 'func'; did you mean 'C::func'?}} \ + // expected-error {{no viable conversion from 'B::B' to 'C::C'}} + func(C::C()); + A::A() + A::A(); + B::B() + B::B(); + C::C() + C::C(); + D::D() + D::D(); // expected-error {{invalid operands to binary expression ('D::D' and 'D::D')}} + } +} + +// PR6716 +namespace test1 { + template class A { + template friend void foo(A &, U); // expected-note {{not viable: 1st argument ('const A') would lose const qualifier}} + + public: + A(); + }; + + void test() { + const A a; + foo(a, 10); // expected-error {{no matching function for call to 'foo'}} + } +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp new file mode 100644 index 0000000..c207283 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s + +// C++98 [basic.lookup.classref]p1: +// In a class member access expression (5.2.5), if the . or -> token is +// immediately followed by an identifier followed by a <, the identifier must +// be looked up to determine whether the < is the beginning of a template +// argument list (14.2) or a less-than operator. The identifier is first +// looked up in the class of the object expression. If the identifier is not +// found, it is then looked up in the context of the entire postfix-expression +// and shall name a class or function template. If the lookup in the class of +// the object expression finds a template, the name is also looked up in the +// context of the entire postfix-expression and +// -- if the name is not found, the name found in the class of the object +// expression is used, otherwise +// -- if the name is found in the context of the entire postfix-expression +// and does not name a class template, the name found in the class of the +// object expression is used, otherwise +// -- if the name found is a class template, it must refer to the same +// entity as the one found in the class of the object expression, +// otherwise the program is ill-formed. + +// From PR 7247 +template +struct set{}; // expected-note{{lookup from the current scope refers here}} +struct Value { + template + void set(T value) {} // expected-note{{lookup in the object type 'Value' refers here}} + + void resolves_to_same() { + Value v; + v.set(3.2); + } +}; +void resolves_to_different() { + { + Value v; + // The fact that the next line is a warning rather than an error is an + // extension. + v.set(3.2); // expected-warning{{lookup of 'set' in member access expression is ambiguous; using member of 'Value'}} + } + { + int set; // Non-template. + Value v; + v.set(3.2); + } +} + +namespace rdar9915664 { + struct A { + template void a(); + }; + + struct B : A { }; + + struct C : A { }; + + struct D : B, C { + A &getA() { return static_cast(*this); } + + void test_a() { + getA().a(); + } + }; +} + +namespace PR11856 { + template T end(T); + + template + void Foo() { + T it1; + if (it1->end < it1->end) { + } + } + + template T *end(T*); + + class X { }; + template + void Foo2() { + T it1; + if (it1->end < it1->end) { + } + + X *x; + if (x->end < 7) { // expected-error{{no member named 'end' in 'PR11856::X'}} + } + } +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp new file mode 100644 index 0000000..cd7e669 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [basic.lookup.classref]p3: +// If the unqualified-id is ~type-name, the type-name is looked up in the +// context of the entire postfix-expression. If the type T of the object +// expression is of a class type C, the type-name is also looked up in the +// scope of class C. At least one of the lookups shall find a name that +// refers to (possibly cv-qualified) T. + +// From core issue 305 +struct A { +}; + +struct C { + struct A {}; + void f (); +}; + +void C::f () { + ::A *a; + a->~A (); +} + +// From core issue 414 +struct X {}; +void f() { + X x; + struct X {}; + x.~X(); +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp new file mode 100644 index 0000000..004d1e4 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test0 { + struct A { + static int foo; + }; + + namespace i0 { + typedef int A; // expected-note {{declared here}} + + int test() { + struct A a; // expected-error {{elaborated type refers to a typedef}} + return a.foo; + } + } + + namespace i1 { + template class A; // expected-note {{declared here}} + + int test() { + struct A a; // expected-error {{elaborated type refers to a template}} + return a.foo; + } + } + + namespace i2 { + int A; + + int test() { + struct A a; + return a.foo; + } + } + + namespace i3 { + void A(); + + int test() { + struct A a; + return a.foo; + } + } + + namespace i4 { + template void A(); + + int test() { + struct A a; + return a.foo; + } + } + + // This should magically be okay; see comment in SemaDecl.cpp. + // rdar://problem/7898108 + typedef struct A A; + int test() { + struct A a; + return a.foo; + } +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp new file mode 100644 index 0000000..8126d28 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/templateid.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// elaborated-type-specifier: +// class-key '::'? nested-name-specifier? 'template'? simple-template-id +// Tests that this form is accepted by the compiler but does not follow +// the elaborated lookup rules of [basic.lookup.elab]. + +template class Ident {}; // expected-note {{previous use is here}} + +namespace A { + template void Ident(); + + class Ident AIdent; // expected-error {{refers to a function template}} + class ::Ident AnotherIdent; +} + +class Ident GlobalIdent; +union Ident GlobalIdent2; // expected-error {{ tag type that does not match }} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp new file mode 100644 index 0000000..7ecedd5 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct X0 { + X0 f1(); + X0 f2(); +}; + +template +struct X1 { + X1(int); + (X1)(float); + X1 f2(); + X1 f2(int); + X1 f2(float); +}; + +// Error recovery: out-of-line constructors whose names have template arguments. +template X1::X1(int) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}} +template (X1::X1)(float) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}} + +// Error recovery: out-of-line constructor names intended to be types +X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type wherever a constructor can be declared}} + +struct X0::X0 X0::f2() { return X0(); } + +template X1::X1 X1::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} +template X1::X1 (X1::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} +template struct X1::X1 (X1::f2)(float) { } diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp new file mode 100644 index 0000000..3039396 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace Ints { + int zero = 0; // expected-note {{candidate found by name lookup is 'Ints::zero'}} + void f(int); // expected-note 3 {{candidate function}} + void g(int); +} + +namespace Floats { + float zero = 0.0f; // expected-note {{candidate found by name lookup is 'Floats::zero'}} + void f(float); // expected-note 3 {{candidate function}} + void g(float); +} + +namespace Numbers { + using namespace Ints; + using namespace Floats; +} + +void test() { + int i = Ints::zero; + Ints::f(i); + + float f = Floats::zero; + Floats::f(f); + + double n = Numbers::zero; // expected-error {{reference to 'zero' is ambiguous}} + Numbers::f(n); // expected-error{{call to 'f' is ambiguous}} + Numbers::f(i); + Numbers::f(f); +} + +namespace Numbers { + struct Number { // expected-note 2 {{candidate}} + explicit Number(double d) : d(d) {} + double d; + }; + Number zero(0.0f); + void g(Number); // expected-note 2{{passing argument to parameter here}} +} + +void test2() { + Numbers::Number n = Numbers::zero; + Numbers::f(n); // expected-error {{no matching function for call to 'f'}} + Numbers::g(n); +} + +namespace Numbers2 { + using Numbers::f; + using Numbers::g; +} + +void test3() { + Numbers::Number n = Numbers::zero; + Numbers2::f(n); // expected-error {{no matching function for call to 'f'}} + Numbers2::g(n); + + int i = Ints::zero; + Numbers2::f(i); + Numbers2::g(i); // expected-error {{no viable conversion from 'int' to 'Numbers::Number'}} + + float f = Floats::zero; + Numbers2::f(f); + Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'Numbers::Number'}} +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp new file mode 100644 index 0000000..dc0f8b4 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p3.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// This is basically paraphrased from the standard. + +namespace Root { + int i = 0; + void f(); +} + +namespace A { + using namespace Root; +} + +namespace B { + using namespace Root; +} + +namespace AB { + using namespace A; + using namespace B; +} + +void test() { + if (AB::i) + AB::f(); +} + +namespace C { + using Root::i; + using Root::f; +} + +namespace AC { + using namespace A; + using namespace C; +} + +void test2() { + if (AC::i) + AC::f(); +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp new file mode 100644 index 0000000..38eccfa --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p4.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace A { + int a; +} + +namespace C { + int c; +} + +namespace B { + using namespace C; + int b; +} + +namespace C { + using namespace B; + using namespace A; +} + +void test() { + C::a++; + C::b++; + C::c++; +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp new file mode 100644 index 0000000..5045bac --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p5.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace A { + struct x {}; // expected-note {{candidate found by name lookup is 'A::x'}} + int x; // expected-note {{candidate found by name lookup is 'A::x'}} + + struct y {}; // expected-note {{type declaration hidden}} + + struct z; + void z(float); +} + +namespace B { + struct x {}; // expected-note {{candidate found by name lookup is 'B::x'}} + float x; // expected-note {{candidate found by name lookup is 'B::x'}} + + float y; // expected-note {{declaration hides type}} + + void z(int); +} + +namespace AB { + using namespace A; + using namespace B; +} + +void test() { + struct AB::x foo; // expected-error {{reference to 'x' is ambiguous}} + int i = AB::x; // expected-error {{reference to 'x' is ambiguous}} + + struct AB::y bar; + float f = AB::y; // expected-error {{a type named 'y' is hidden by a declaration in a different namespace}} + AB::z(i); + AB::z(f); +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp new file mode 100644 index 0000000..c745c84 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// XFAIL: * +// Our C++0x doesn't currently have specialized destructor name handling, +// since the specification is still in flux. +struct C { + typedef int I; +}; + +typedef int I1, I2; +extern int* p; +extern int* q; + +void f() { + p->C::I::~I(); + q->I1::~I2(); +} + +struct A { + ~A(); +}; + +typedef A AB; +int main() { + AB *p; + p->AB::~AB(); +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp new file mode 100644 index 0000000..0956de3 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct C { + typedef int I; +}; + +typedef int I1, I2; +extern int* p; +extern int* q; + +void f() { + p->C::I::~I(); + q->I1::~I2(); +} + +struct A { + ~A(); +}; + +typedef A AB; +int main() { + AB *p; + p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}} +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp new file mode 100644 index 0000000..ab0dc24 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// When looking up a namespace-name in a using-directive or +// namespace-alias-definition, only namespace names are considered. + +struct ns1 {}; +void ns2(); +int ns3 = 0; + +namespace ns0 { + namespace ns1 { + struct test0 {}; + } + namespace ns2 { + struct test1 {}; + } + namespace ns3 { + struct test2 {}; + } +} + +using namespace ns0; + +namespace test3 = ns1; +namespace test4 = ns2; +namespace test5 = ns3; + +using namespace ns1; +using namespace ns2; +using namespace ns3; + +test0 a; +test1 b; +test2 c; + diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp new file mode 100644 index 0000000..a1cf529 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p11.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +static const int a = 10; + +void f0(int a, + int b = a) { // expected-error {{default argument references parameter 'a'}} +} + +template +class A { +}; diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp new file mode 100644 index 0000000..878ff07 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p12.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct S {}; +S E0; + +namespace { + enum { + E0 = 1, + E1 = E0 + 1 + }; +} + + diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp new file mode 100644 index 0000000..58d7ff4 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p13.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct S { + static const int f0 = 0; + static int f1; +}; + +int S::f1 = f0; diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp new file mode 100644 index 0000000..0fa4f65 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [basic.lookup.unqual]p14: +// If a variable member of a namespace is defined outside of the +// scope of its namespace then any name used in the definition of +// the variable member (after the declarator-id) is looked up as if +// the definition of the variable member occurred in its namespace. + +namespace N { + struct S {}; + S i; + extern S j; + extern S j2; +} + +int i = 2; +N::S N::j = i; +N::S N::j2(i); diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp new file mode 100644 index 0000000..253d15e --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// XFAIL: * + +class C { +public: + C(int a, int b); +}; + +C::C(int a, // expected-note {{previous definition}} + int b) // expected-note {{previous definition}} +try { + int c; + +} catch (int a) { // expected-error {{redefinition of 'a'}} + int b; // expected-error {{redefinition of 'b'}} + ++c; // expected-error {{use of undeclared identifier 'c'}} +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp new file mode 100644 index 0000000..20a7ae0 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef int f; + +namespace N0 { + struct A { + friend void f(); + void g() { + int i = f(1); + } + }; +} + +namespace N1 { + struct A { + friend void f(A &); + operator int(); + void g(A a) { + // ADL should not apply to the lookup of 'f', it refers to the typedef + // above. + int i = f(a); + } + }; +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp new file mode 100644 index 0000000..d2afd5d --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR5741 +namespace test0 { + struct A { + struct B { }; + struct C; + }; + + struct A::C : B { }; +} + +// Test that successive base specifiers don't screw with each other. +namespace test1 { + struct Opaque1 {}; + struct Opaque2 {}; + + struct A { + struct B { B(Opaque1); }; + }; + struct B { + B(Opaque2); + }; + + struct C : A, B { + // Apparently the base-or-member lookup is actually ambiguous + // without this qualification. + C() : A(), test1::B(Opaque2()) {} + }; +} + +// Test that we don't find the injected class name when parsing base +// specifiers. +namespace test2 { + template struct bar {}; + template struct foo : bar {}; // expected-error {{use of class template foo requires template arguments}} expected-note {{template is declared here}} +} diff --git a/clang/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp new file mode 100644 index 0000000..911df98 --- /dev/null +++ b/clang/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// rdar4641403 +namespace N { + struct X { // expected-note{{candidate found by name lookup}} + float b; + }; +} + +using namespace N; + +typedef struct { + int a; +} X; // expected-note{{candidate found by name lookup}} + + +struct Y { }; +void Y(int) { } + +void f() { + X *x; // expected-error{{reference to 'X' is ambiguous}} + Y(1); // okay +} + diff --git a/clang/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp new file mode 100644 index 0000000..cd51c78 --- /dev/null +++ b/clang/test/CXX/basic/basic.scope/basic.scope.local/p4-0x.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +void f() { + int b; + int arr[] = {1, 2, 3}; + + if (bool b = true) // expected-note 2{{previous definition}} + bool b; // expected-error {{redefinition}} + else + int b; // expected-error {{redefinition}} + while (bool b = true) // expected-note {{previous definition}} + int b; // expected-error {{redefinition}} + for (int c; // expected-note 2{{previous definition}} + bool c = true;) // expected-error {{redefinition}} + double c; // expected-error {{redefinition}} + switch (int n = 37 + 5) // expected-note {{previous definition}} + int n; // expected-error {{redefinition}} + for (int a : arr) // expected-note {{previous definition}} + int a = 0; // expected-error {{redefinition}} + + if (bool b = true) { // expected-note 2{{previous definition}} + int b; // expected-error {{redefinition}} + } else { + int b; // expected-error {{redefinition}} + } + while (bool b = true) { // expected-note {{previous definition}} + int b; // expected-error {{redefinition}} + } + for (int c; // expected-note 2{{previous definition}} + bool c = true;) { // expected-error {{redefinition}} + double c; // expected-error {{redefinition}} + } + switch (int n = 37 + 5) { // expected-note {{previous definition}} + int n; // expected-error {{redefinition}} + } + for (int &a : arr) { // expected-note {{previous definition}} + int a = 0; // expected-error {{redefinition}} + } + + if (bool b = true) {{ // expected-note {{previous definition}} + bool b; + }} else { + int b; // expected-error {{redefinition}} + } + if (bool b = true) { // expected-note {{previous definition}} + bool b; // expected-error {{redefinition}} + } else {{ + int b; + }} + if (bool b = true) {{ + bool b; + }} else {{ + int b; + }} + while (bool b = true) {{ + int b; + }} + for (int c; // expected-note {{previous definition}} + bool c = true; ) {{ // expected-error {{redefinition}} + double c; + }} + switch (int n = 37 + 5) {{ + int n; + }} + for (int &a : arr) {{ + int a = 0; + }} +} diff --git a/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp new file mode 100644 index 0000000..407a5f7 --- /dev/null +++ b/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p3.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// Classes. +namespace Class { + namespace NS { + class C {}; // expected-note {{candidate}} + } + using namespace NS; + class C : C {}; // expected-error {{reference to 'C' is ambiguous}} \ + expected-note {{candidate}} +} + +// Enumerations. +enum E { + EPtrSize = sizeof((E*)0) // ok, E is already declared +}; + +// Alias declarations. clang implements the proposed resolution to N1044. +namespace Alias { + namespace NS { + class C; + } + using namespace NS; + using C = C; // ok, C = B::C + using C = NS::C; // ok, same type +} diff --git a/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp new file mode 100644 index 0000000..e64b675 --- /dev/null +++ b/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Template type parameters. +typedef unsigned char T; +template struct X0 { }; +template<> struct X0 { static const bool value = true; }; +int array0[X0<>::value? 1 : -1]; + +// Non-type template parameters. +const int N = 17; +template struct X1 { }; +template<> struct X1<17> { static const bool value = true; }; +int array1[X1<>::value? 1 : -1]; + +// Template template parameters. +template class X0 = X0> struct X2 { }; +template<> struct X2 { static const bool value = true; }; +int array2[X2<>::value? 1 : -1]; diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2a.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2a.cpp new file mode 100644 index 0000000..b8dfbe7 --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2a.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef int Int; +typedef char Char; +typedef Char* Carp; + +Int main(Int argc, Carp argv[]) { +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2b.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2b.cpp new file mode 100644 index 0000000..785382c --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2b.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef int Int; +typedef char Char; +typedef Char* Carp; + +Int main(Int argc, Carp argv[], Char *env[]) { +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2c.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2c.cpp new file mode 100644 index 0000000..81b08b9 --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2c.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int main() { +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2d.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2d.cpp new file mode 100644 index 0000000..bcdbdb2 --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2d.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +static int main() { // expected-error {{'main' is not allowed to be declared static}} +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2e.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2e.cpp new file mode 100644 index 0000000..954fdbd --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2e.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +inline int main() { // expected-error {{'main' is not allowed to be declared inline}} +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2f.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2f.cpp new file mode 100644 index 0000000..ea5a752 --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2f.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void // expected-error {{'main' must return 'int'}} +main( // expected-error {{first parameter of 'main' (argument count) must be of type 'int'}} + float a +) { +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2g.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2g.cpp new file mode 100644 index 0000000..e3209fd --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2g.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int main(int argc, const char* const* argv) { +} diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2h.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2h.cpp new file mode 100644 index 0000000..abf8faa --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2h.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +int main() { } // expected-error{{'main' cannot be a template}} + diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2i.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2i.cpp new file mode 100644 index 0000000..db8da3c --- /dev/null +++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2i.cpp @@ -0,0 +1,6 @@ +// RUN: cp %s %t +// RUN: %clang_cc1 -x c++ %s -std=c++11 -fsyntax-only -verify +// RUN: not %clang_cc1 -x c++ %t -std=c++11 -fixit +// RUN: %clang_cc1 -x c++ %t -std=c++11 -fsyntax-only + +constexpr int main() { } // expected-error{{'main' is not allowed to be declared constexpr}} diff --git a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp new file mode 100644 index 0000000..8a62ae8 --- /dev/null +++ b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +#include + +struct A { + void *operator new(size_t); +}; + +namespace NS { + void *operator new(size_t);; // expected-error {{'operator new' cannot be declared inside a namespace}} +} + +static void *operator new(size_t); // expected-error {{'operator new' cannot be declared static in global scope}} + +struct B { + void operator new(size_t); // expected-error {{'operator new' must return type 'void *'}} +}; + +struct C { + void *operator new(); // expected-error {{'operator new' must have at least one parameter}} +}; + +struct D { + void *operator new(bool); // expected-error {{'operator new' takes type size_t}} +}; + +struct E { + void *operator new(size_t = 0); // expected-error {{parameter of 'operator new' cannot have a default argument}} +}; + +struct F { + template void *operator new(size_t, int); +}; + +struct G { + template T operator new(size_t, int); // expected-error {{'operator new' cannot have a dependent return type; use 'void *' instead}} +}; + +struct H { + template void *operator new(T, int); // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}} +}; + +struct I { + template void *operator new(size_t); // expected-error {{'operator new' template must have at least two parameters}} +}; diff --git a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp new file mode 100644 index 0000000..e00e948 --- /dev/null +++ b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + void operator delete(void*); +}; + +namespace NS { + void operator delete(void *); // expected-error {{'operator delete' cannot be declared inside a namespace}} +} + +static void operator delete(void *); // expected-error {{'operator delete' cannot be declared static in global scope}} diff --git a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp new file mode 100644 index 0000000..6cd587c --- /dev/null +++ b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-nodef.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int *use_new(int N) { + return new int [N]; +} + +int std = 17; diff --git a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp new file mode 100644 index 0000000..4567c46 --- /dev/null +++ b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2-noexceptions.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +namespace std { + class bad_alloc { }; + + typedef __SIZE_TYPE__ size_t; +} + +class foo { virtual ~foo(); }; + +void* operator new(std::size_t); +void* operator new[](std::size_t); +void operator delete(void*); +void operator delete[](void*); diff --git a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp new file mode 100644 index 0000000..47b5158 --- /dev/null +++ b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/p2.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s +int *use_new(int N) { + if (N == 1) + return new int; + + return new int [N]; +} + +void use_delete(int* ip, int N) { + if (N == 1) + delete ip; + else + delete [] ip; +} + +namespace std { + class bad_alloc { }; + + typedef __SIZE_TYPE__ size_t; +} + +void* operator new(std::size_t) throw(std::bad_alloc); // expected-note{{previous declaration}} +void* operator new[](std::size_t) throw(std::bad_alloc); +void operator delete(void*) throw(); // expected-note{{previous declaration}} +void operator delete[](void*) throw(); + +void* operator new(std::size_t); // expected-warning{{'operator new' is missing exception specification 'throw(std::bad_alloc)'}} +void operator delete(void*); // expected-warning{{'operator delete' is missing exception specification 'throw()'}} diff --git a/clang/test/CXX/basic/basic.types/p10.cpp b/clang/test/CXX/basic/basic.types/p10.cpp new file mode 100644 index 0000000..83b910b --- /dev/null +++ b/clang/test/CXX/basic/basic.types/p10.cpp @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct NonLiteral { NonLiteral(); }; + +// A type is a literal type if it is: + +// - a scalar type +constexpr int f1(double) { return 0; } + +// - a reference type +struct S { S(); }; +constexpr int f2(S &) { return 0; } + +// FIXME: I'm not entirely sure whether the following is legal or not... +struct BeingDefined; +extern BeingDefined beingdefined; +struct BeingDefined { + static constexpr BeingDefined& t = beingdefined; +}; + +// - a class type that has all of the following properties: + +// (implied) - it is complete + +struct Incomplete; +template struct ClassTemp {}; + +constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} +constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} +constexpr ClassTemp classtemplate = {}; +constexpr ClassTemp classtemplate2[] = {}; + +// - it has a trivial destructor +struct UserProvDtor { + constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} + ~UserProvDtor(); // expected-note {{has a user-provided destructor}} +}; + +struct NonTrivDtor { + constexpr NonTrivDtor(); + constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} + virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} +}; +struct NonTrivDtorBase { + ~NonTrivDtorBase(); +}; +template +struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}} + constexpr DerivedFromNonTrivDtor(); +}; +constexpr int f(DerivedFromNonTrivDtor) { return 0; } // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor' is not a literal type}} +struct TrivDtor { + constexpr TrivDtor(); +}; +constexpr int f(TrivDtor) { return 0; } +struct TrivDefaultedDtor { + constexpr TrivDefaultedDtor(); + ~TrivDefaultedDtor() = default; +}; +constexpr int f(TrivDefaultedDtor) { return 0; } + +// - it is an aggregate type or has at least one constexpr constructor or +// constexpr constructor template that is not a copy or move constructor +struct Agg { + int a; + char *b; +}; +constexpr int f3(Agg a) { return a.a; } +struct CtorTemplate { + template constexpr CtorTemplate(T); +}; +struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} + constexpr CopyCtorOnly(CopyCtorOnly&); + constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} +}; +struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} + constexpr MoveCtorOnly(MoveCtorOnly&&); + constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} +}; +template +struct CtorArg { + constexpr CtorArg(T); +}; +constexpr int f(CtorArg) { return 0; } // ok +constexpr int f(CtorArg) { return 0; } // ok, ctor is still constexpr +// We have a special-case diagnostic for classes with virtual base classes. +struct VBase {}; +struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}} +struct Derived : HasVBase { + constexpr Derived() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} +}; +template struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}} + constexpr DerivedFromVBase(); +}; +constexpr int f(DerivedFromVBase) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase' is not a literal type}} +template constexpr DerivedFromVBase::DerivedFromVBase() : T() {} +constexpr int nVBase = (DerivedFromVBase(), 0); // expected-error {{constant expression}} expected-note {{cannot construct object of type 'DerivedFromVBase' with virtual base class in a constant expression}} + +// - it has all non-static data members and base classes of literal types +struct NonLitMember { + S s; // expected-note {{has data member 's' of non-literal type 'S'}} +}; +constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitMember' is not a literal type}} +struct NonLitBase : + S { // expected-note {{base class 'S' of non-literal type}} + constexpr NonLitBase(); + constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} +}; +struct LitMemBase : Agg { + Agg agg; +}; +template +struct MemberType { + T t; // expected-note {{'MemberType' is not literal because it has data member 't' of non-literal type 'NonLiteral'}} + constexpr MemberType(); +}; +constexpr int f(MemberType) { return 0; } +constexpr int f(MemberType) { return 0; } // expected-error {{not a literal type}} + +// - an array of literal type +struct ArrGood { + Agg agg[24]; + double d[12]; + TrivDtor td[3]; + TrivDefaultedDtor tdd[3]; +}; +constexpr int f(ArrGood) { return 0; } + +struct ArrBad { + S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}} +}; +constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}} diff --git a/clang/test/CXX/class.access/class.access.base/p1.cpp b/clang/test/CXX/class.access/class.access.base/p1.cpp new file mode 100644 index 0000000..43cc99e --- /dev/null +++ b/clang/test/CXX/class.access/class.access.base/p1.cpp @@ -0,0 +1,155 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [class.access.base]p1(a): +// If a class is declared to be a base class for another class using +// the public access specifier, the public members of the base class +// are accessible as public members of the derived class and protected +// members of the base class are accessible as protected members of +// the derived class. +namespace test0 { + class Base { + public: int pub; static int spub; + protected: int prot; static int sprot; // expected-note 4 {{declared protected here}} + private: int priv; static int spriv; // expected-note 8 {{declared private here}} + }; + + class Test : public Base { + void test() { + pub++; + spub++; + prot++; + sprot++; + priv++; // expected-error {{private member}} + spriv++; // expected-error {{private member}} + + Base::pub++; + Base::spub++; + Base::prot++; + Base::sprot++; + Base::priv++; // expected-error {{private member}} + Base::spriv++; // expected-error {{private member}} + } + }; + + void test(Test *t) { + t->pub++; + t->spub++; + t->prot++; // expected-error {{protected member}} + t->sprot++; // expected-error {{protected member}} + t->priv++; // expected-error {{private member}} + t->spriv++; // expected-error {{private member}} + + t->Base::pub++; + t->Base::spub++; + t->Base::prot++; // expected-error {{protected member}} + t->Base::sprot++; // expected-error {{protected member}} + t->Base::priv++; // expected-error {{private member}} + t->Base::spriv++; // expected-error {{private member}} + } +} + +// C++0x [class.access.base]p1(b): +// If a class is declared to be a base class for another class using +// the protected access specifier, the public and protected members +// of the base class are accessible as protected members of the +// derived class. +namespace test1 { + class Base { // expected-note 6{{member is declared here}} + public: + int pub; // expected-note{{member is declared here}} + static int spub; // expected-note{{member is declared here}} + protected: int prot; static int sprot; // expected-note 4 {{declared protected here}} + private: int priv; static int spriv; // expected-note 8 {{declared private here}} + }; + + class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}} + void test() { + pub++; + spub++; + prot++; + sprot++; + priv++; // expected-error {{private member}} + spriv++; // expected-error {{private member}} + + Base::pub++; + Base::spub++; + Base::prot++; + Base::sprot++; + Base::priv++; // expected-error {{private member}} + Base::spriv++; // expected-error {{private member}} + } + }; + + void test(Test *t) { + t->pub++; // expected-error {{protected member}} expected-error {{protected base class}} + t->spub++; // expected-error {{protected member}} + t->prot++; // expected-error {{protected member}} expected-error {{protected base class}} + t->sprot++; // expected-error {{protected member}} + t->priv++; // expected-error {{private member}} expected-error {{protected base class}} + t->spriv++; // expected-error {{private member}} + + // Two possible errors here: one for Base, one for the member + t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}} + t->Base::spub++; // expected-error {{protected member}} + t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}} + t->Base::sprot++; // expected-error 2 {{protected member}} + t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}} + t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}} + } +} + +// C++0x [class.access.base]p1(b): +// If a class is declared to be a base class for another class using +// the private access specifier, the public and protected members of +// the base class are accessible as private members of the derived +// class. +namespace test2 { + class Base { // expected-note 6{{member is declared here}} + public: + int pub; // expected-note{{member is declared here}} + static int spub; // expected-note{{member is declared here}} + protected: + int prot; // expected-note {{declared protected here}} \ + // expected-note{{member is declared here}} + static int sprot; // expected-note {{declared protected here}} \ + // expected-note{{member is declared here}} + private: + int priv; // expected-note 4 {{declared private here}} + static int spriv; // expected-note 4 {{declared private here}} + }; + + class Test : private Base { // expected-note 6 {{declared private here}} \ + // expected-note 10 {{constrained by private inheritance here}} + void test() { + pub++; + spub++; + prot++; + sprot++; + priv++; // expected-error {{private member}} + spriv++; // expected-error {{private member}} + + Base::pub++; + Base::spub++; + Base::prot++; + Base::sprot++; + Base::priv++; // expected-error {{private member}} + Base::spriv++; // expected-error {{private member}} + } + }; + + void test(Test *t) { + t->pub++; // expected-error {{private member}} expected-error {{private base class}} + t->spub++; // expected-error {{private member}} + t->prot++; // expected-error {{private member}} expected-error {{private base class}} + t->sprot++; // expected-error {{private member}} + t->priv++; // expected-error {{private member}} expected-error {{private base class}} + t->spriv++; // expected-error {{private member}} + + t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}} + t->Base::spub++; // expected-error {{private member}} + t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}} + t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}} + t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}} + t->Base::spriv++; // expected-error 2 {{private member}} + } +} diff --git a/clang/test/CXX/class.access/class.access.base/p5.cpp b/clang/test/CXX/class.access/class.access.base/p5.cpp new file mode 100644 index 0000000..255fbfc --- /dev/null +++ b/clang/test/CXX/class.access/class.access.base/p5.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -verify %s + +namespace test0 { + struct A { + static int x; + }; + struct B : A {}; + struct C : B {}; + + int test() { + return A::x + + B::x + + C::x; + } +} + +namespace test1 { + struct A { + private: static int x; // expected-note 5 {{declared private here}} + static int test() { return x; } + }; + struct B : public A { + static int test() { return x; } // expected-error {{private member}} + }; + struct C : private A { + static int test() { return x; } // expected-error {{private member}} + }; + + struct D { + public: static int x; // expected-note{{member is declared here}} + static int test() { return x; } + }; + struct E : private D { // expected-note{{constrained by private inheritance}} + static int test() { return x; } + }; + + int test() { + return A::x // expected-error {{private member}} + + B::x // expected-error {{private member}} + + C::x // expected-error {{private member}} + + D::x + + E::x; // expected-error {{private member}} + } +} + +namespace test2 { + class A { + protected: static int x; // expected-note{{member is declared here}} + }; + + class B : private A {}; // expected-note {{private inheritance}} + class C : private A { + int test(B *b) { + return b->x; // expected-error {{private member}} + } + }; +} + +namespace test3 { + class A { + protected: static int x; + }; + + class B : public A {}; + class C : private A { + int test(B *b) { + // x is accessible at C when named in A. + // A is an accessible base of B at C. + // Therefore this succeeds. + return b->x; + } + }; +} + +// TODO: flesh out these cases diff --git a/clang/test/CXX/class.access/class.access.dcl/p1.cpp b/clang/test/CXX/class.access/class.access.dcl/p1.cpp new file mode 100644 index 0000000..aab5fff --- /dev/null +++ b/clang/test/CXX/class.access/class.access.dcl/p1.cpp @@ -0,0 +1,199 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// This is just the test for [namespace.udecl]p4 with 'using' +// uniformly stripped out. + +// C++03 [namespace.udecl]p4: +// A using-declaration used as a member-declaration shall refer to a +// member of a base class of the class being defined, shall refer to +// a member of an anonymous union that is a member of a base class +// of the class being defined, or shall refer to an enumerator for +// an enumeration type that is a member of a base class of the class +// being defined. + +// There is no directly analogous paragraph in C++0x, and the feature +// works sufficiently differently there that it needs a separate test. + +namespace test0 { + namespace NonClass { + typedef int type; + struct hiding {}; + int hiding; + static union { double union_member; }; + enum tagname { enumerator }; + } + + class Test0 { + NonClass::type; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} + NonClass::hiding; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} + NonClass::union_member; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} + NonClass::enumerator; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} + }; +} + +struct Opaque0 {}; + +namespace test1 { + struct A { + typedef int type; + struct hiding {}; // expected-note {{previous use is here}} + Opaque0 hiding; + union { double union_member; }; + enum tagname { enumerator }; + }; + + struct B : A { + A::type; // expected-warning {{access declarations are deprecated}} + A::hiding; // expected-warning {{access declarations are deprecated}} + A::union_member; // expected-warning {{access declarations are deprecated}} + A::enumerator; // expected-warning {{access declarations are deprecated}} + A::tagname; // expected-warning {{access declarations are deprecated}} + + void test0() { + type t = 0; + } + + void test1() { + typedef struct A::hiding local; + struct hiding _ = local(); + } + + void test2() { + union hiding _; // expected-error {{tag type that does not match previous}} + } + + void test3() { + char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; + } + + void test4() { + enum tagname _ = enumerator; + } + + void test5() { + Opaque0 _ = hiding; + } + }; +} + +namespace test2 { + struct A { + typedef int type; + struct hiding {}; // expected-note {{previous use is here}} + int hiding; + union { double union_member; }; + enum tagname { enumerator }; + }; + + template struct B : A { + A::type; // expected-warning {{access declarations are deprecated}} + A::hiding; // expected-warning {{access declarations are deprecated}} + A::union_member; // expected-warning {{access declarations are deprecated}} + A::enumerator; // expected-warning {{access declarations are deprecated}} + A::tagname; // expected-warning {{access declarations are deprecated}} + + void test0() { + type t = 0; + } + + void test1() { + typedef struct A::hiding local; + struct hiding _ = local(); + } + + void test2() { + union hiding _; // expected-error {{tag type that does not match previous}} + } + + void test3() { + char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; + } + + void test4() { + enum tagname _ = enumerator; + } + + void test5() { + Opaque0 _ = hiding; + } + }; +} + +namespace test3 { + struct hiding {}; + + template struct A { + typedef int type; // expected-note {{target of using declaration}} + struct hiding {}; + Opaque0 hiding; + union { double union_member; }; + enum tagname { enumerator }; // expected-note {{target of using declaration}} + }; + + template struct B : A { + A::type; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}} + A::hiding; // expected-warning {{access declarations are deprecated}} + A::union_member; // expected-warning {{access declarations are deprecated}} + A::enumerator; // expected-warning {{access declarations are deprecated}} + A::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}} + + // FIXME: re-enable these when the various bugs involving tags are fixed +#if 0 + void test1() { + typedef struct A::hiding local; + struct hiding _ = local(); + } + + void test2() { + typedef struct A::hiding local; + union hiding _ = local(); + } +#endif + + void test3() { + char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; + } + +#if 0 + void test4() { + enum tagname _ = enumerator; + } +#endif + + void test5() { + Opaque0 _ = hiding; + } + }; + + template struct B; // expected-note {{in instantiation}} +} + +namespace test4 { + struct Base { + int foo(); + }; + + struct Unrelated { + int foo(); + }; + + struct Subclass : Base { + }; + + namespace InnerNS { + int foo(); + } + + // We should be able to diagnose these without instantiation. + template struct C : Base { + InnerNS::foo; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}} + Base::bar; // expected-error {{no member named 'bar'}} expected-warning {{access declarations are deprecated}} + Unrelated::foo; // expected-error {{not a base class}} expected-warning {{access declarations are deprecated}} + C::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}} + Subclass::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}} + + int bar(); //expected-note {{target of using declaration}} + C::bar; // expected-error {{refers to its own class}} expected-warning {{access declarations are deprecated}} + }; +} + diff --git a/clang/test/CXX/class.access/class.access.nest/p1.cpp b/clang/test/CXX/class.access/class.access.nest/p1.cpp new file mode 100644 index 0000000..eceffcf --- /dev/null +++ b/clang/test/CXX/class.access/class.access.nest/p1.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Derived from GNU's std::string +namespace test0 { + class A { + struct B { + unsigned long length; + }; + struct C : B { + static const unsigned long max_length; + }; + }; + + const unsigned long A::C::max_length = sizeof(B); +} + +// Example from the standard. +namespace test1 { + class E { + int x; + class B {}; + + class I { + B b; + int y; // expected-note {{declared private here}} + void f(E* p, int i) { + p->x = i; + } + }; + + int g(I* p) { return p->y; } // expected-error {{'y' is a private member of 'test1::E::I'}} + }; +} diff --git a/clang/test/CXX/class.access/class.friend/p1.cpp b/clang/test/CXX/class.access/class.friend/p1.cpp new file mode 100644 index 0000000..68ff83f --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p1.cpp @@ -0,0 +1,356 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++'0x [class.friend] p1: +// A friend of a class is a function or class that is given permission to use +// the private and protected member names from the class. A class specifies +// its friends, if any, by way of friend declarations. Such declarations give +// special access rights to the friends, but they do not make the nominated +// friends members of the befriending class. + +struct S { static void f(); }; +S* g() { return 0; } + +struct X { + friend struct S; + friend S* g(); +}; + +void test1() { + S s; + g()->f(); + S::f(); + X::g(); // expected-error{{no member named 'g' in 'X'}} + X::S x_s; // expected-error{{no member named 'S' in 'X'}} + X x; + x.g(); // expected-error{{no member named 'g' in 'X'}} +} + +// Test that we recurse through namespaces to find already declared names, but +// new names are declared within the enclosing namespace. +namespace N { + struct X { + friend struct S; + friend S* g(); + + friend struct S2; + friend struct S2* g2(); + }; + + struct S2 { static void f2(); }; + S2* g2() { return 0; } + + void test() { + g()->f(); + S s; + S::f(); + X::g(); // expected-error{{no member named 'g' in 'N::X'}} + X::S x_s; // expected-error{{no member named 'S' in 'N::X'}} + X x; + x.g(); // expected-error{{no member named 'g' in 'N::X'}} + + g2(); + S2 s2; + ::g2(); // expected-error{{no member named 'g2' in the global namespace}} + ::S2 g_s2; // expected-error{{no member named 'S2' in the global namespace}} + X::g2(); // expected-error{{no member named 'g2' in 'N::X'}} + X::S2 x_s2; // expected-error{{no member named 'S2' in 'N::X'}} + x.g2(); // expected-error{{no member named 'g2' in 'N::X'}} + } +} + +namespace test0 { + class ClassFriend { + void test(); + }; + + class MemberFriend { + void test(); + }; + + void declared_test(); + + class Class { + static void member(); // expected-note 2 {{declared private here}} + + friend class ClassFriend; + friend class UndeclaredClassFriend; + + friend void undeclared_test(); + friend void declared_test(); + friend void MemberFriend::test(); + }; + + void declared_test() { + Class::member(); + } + + void undeclared_test() { + Class::member(); + } + + void unfriended_test() { + Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} + } + + void ClassFriend::test() { + Class::member(); + } + + void MemberFriend::test() { + Class::member(); + } + + class UndeclaredClassFriend { + void test() { + Class::member(); + } + }; + + class ClassNonFriend { + void test() { + Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} + } + }; +} + +// Make sure that friends have access to inherited protected members. +namespace test2 { + struct X; + + class ilist_half_node { + friend struct ilist_walker_bad; + X *Prev; + protected: + X *getPrev() { return Prev; } // expected-note{{member is declared here}} + }; + + class ilist_node : private ilist_half_node { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}} + friend struct ilist_walker; + X *Next; + X *getNext() { return Next; } // expected-note {{declared private here}} + }; + + struct X : ilist_node {}; + + struct ilist_walker { + static X *getPrev(X *N) { return N->getPrev(); } + static X *getNext(X *N) { return N->getNext(); } + }; + + struct ilist_walker_bad { + static X *getPrev(X *N) { return N->getPrev(); } // \ + // expected-error {{'getPrev' is a private member of 'test2::ilist_half_node'}} \ + // expected-error {{cannot cast 'test2::X' to its private base class 'test2::ilist_half_node'}} + + static X *getNext(X *N) { return N->getNext(); } // \ + // expected-error {{'getNext' is a private member of 'test2::ilist_node'}} + }; +} + +namespace test3 { + class A { protected: int x; }; // expected-note {{declared protected here}} + + class B : public A { + friend int foo(B*); + }; + + int foo(B *p) { + return p->x; + } + + int foo(const B *p) { + return p->x; // expected-error {{'x' is a protected member of 'test3::A'}} + } +} + +namespace test3a { + class A { protected: int x; }; + + class B : public A { + friend int foo(B*); + }; + + int foo(B * const p) { + return p->x; + } +} + +namespace test4 { + template class Holder { + T object; + friend bool operator==(Holder &a, Holder &b) { + return a.object == b.object; // expected-error {{invalid operands to binary expression}} + } + }; + + struct Inequal {}; + bool test() { + Holder a, b; + return a == b; // expected-note {{requested here}} + } +} + + +// PR6174 +namespace test5 { + namespace ns { + class A; + } + + class ns::A { + private: int x; + friend class B; + }; + + namespace ns { + class B { + int test(A *p) { return p->x; } + }; + } +} + +// PR6207 +namespace test6 { + struct A {}; + + struct B { + friend A::A(); + friend A::~A(); + friend A &A::operator=(const A&); + }; +} + +namespace test7 { + template struct X { + X(); + ~X(); + void foo(); + void bar(); + }; + + class A { + friend void X::foo(); + friend X::X(); + friend X::X(const X&); + + private: + A(); // expected-note 2 {{declared private here}} + }; + + template<> void X::foo() { + A a; + } + + template<> void X::bar() { + A a; // expected-error {{calling a private constructor}} + } + + template<> X::X() { + A a; + } + + template<> X::~X() { + A a; // expected-error {{calling a private constructor}} + } +} + +// Return types, parameters and default arguments to friend functions. +namespace test8 { + class A { + typedef int I; // expected-note 4 {{declared private here}} + static const I x = 0; // expected-note {{implicitly declared private here}} + friend I f(I i); + template friend I g(I i); + }; + + const A::I A::x; + A::I f(A::I i = A::x) {} + template A::I g(A::I i) { + T t; + } + template A::I g(A::I i); + + A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}} + template A::I g2(A::I i) { // expected-error 2 {{is a private member of}} + T t; + } + template A::I g2(A::I i); +} + +// PR6885 +namespace test9 { + class B { + friend class test9; + }; +} + +// PR7230 +namespace test10 { + extern "C" void f(void); + extern "C" void g(void); + + namespace NS { + class C { + void foo(void); // expected-note {{declared private here}} + friend void test10::f(void); + }; + static C* bar; + } + + void f(void) { + NS::bar->foo(); + } + + void g(void) { + NS::bar->foo(); // expected-error {{private member}} + } +} + +// PR8705 +namespace test11 { + class A { + void test0(int); + void test1(int); + void test2(int); + void test3(int); + }; + + class B { + typedef int private_type; // expected-note 2 {{implicitly declared private here}} + friend void A::test0(int); + friend void A::test1(int); + }; + + void A::test0(B::private_type x) {} + void A::test1(int x = B::private_type()) {} + void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}} + void A::test3(int x = B::private_type()) {} // expected-error {{'private_type' is a private member of 'test11::B'}} +} + + +// PR9221 +namespace test12 { + struct A { + void foo(); + }; + class B : private A { + friend void A::foo(); + void *mem; + }; + void A::foo() { + void *var = static_cast(this)->mem; + } +} + +namespace PR9103 { + struct base { + protected: + static void foo(void) {} + }; + + struct cls: base { + friend void bar(void) { + base::foo(); + } + }; +} diff --git a/clang/test/CXX/class.access/class.friend/p11.cpp b/clang/test/CXX/class.access/class.friend/p11.cpp new file mode 100644 index 0000000..a05b2d2 --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p11.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// rdar://problem/8540720 +namespace test0 { + void foo() { + void bar(); + class A { + friend void bar(); + }; + } +} + +namespace test1 { + void foo() { + class A { + friend void bar(); // expected-error {{no matching function found in local scope}} + }; + } +} diff --git a/clang/test/CXX/class.access/class.friend/p2-cxx03.cpp b/clang/test/CXX/class.access/class.friend/p2-cxx03.cpp new file mode 100644 index 0000000..f8cabfd --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p2-cxx03.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template +class X0 { + friend T; // expected-warning{{non-class friend type 'T' is a C++11 extension}} +}; + +class X1 { }; +enum E1 { }; +X0 x0a; +X0 x0b; +X0 x0c; +X0 x0d; + diff --git a/clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp new file mode 100644 index 0000000..00fc0a3 --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +template +class X0 { + friend T; +}; + +class Y1 { }; +enum E1 { }; +X0 x0a; +X0 x0b; +X0 x0c; +X0 x0d; + +template +class X1 { + friend typename T::type; // expected-error{{no type named 'type' in 'Y1'}} +}; + +struct Y2 { + struct type { }; +}; + +struct Y3 { + typedef int type; +}; + +X1 x1a; +X1 x1b; +X1 x1c; // expected-note{{in instantiation of template class 'X1' requested here}} diff --git a/clang/test/CXX/class.access/class.friend/p6.cpp b/clang/test/CXX/class.access/class.friend/p6.cpp new file mode 100644 index 0000000..7f7d909 --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p6.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f1(); + +struct X { + void f2(); +}; + +struct Y { + friend void ::f1() { } // expected-error{{friend function definition cannot be qualified with '::'}} + friend void X::f2() { } // expected-error{{friend function definition cannot be qualified with 'X::'}} +}; + +void local() { + void f(); + + struct Local { + friend void f() { } // expected-error{{friend function cannot be defined in a local class}} + }; +} diff --git a/clang/test/CXX/class.access/class.protected/p1-cxx11.cpp b/clang/test/CXX/class.access/class.protected/p1-cxx11.cpp new file mode 100644 index 0000000..dc9b20d --- /dev/null +++ b/clang/test/CXX/class.access/class.protected/p1-cxx11.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR12497 +namespace test0 { + class A { + protected: + A() {} + A(const A &) {} + ~A() {} + A &operator=(const A &a) { return *this; } + }; + + class B : public A {}; + + void test() { + B b1; + B b2 = b1; + b1 = b2; + } +} diff --git a/clang/test/CXX/class.access/class.protected/p1.cpp b/clang/test/CXX/class.access/class.protected/p1.cpp new file mode 100644 index 0000000..c9491e1 --- /dev/null +++ b/clang/test/CXX/class.access/class.protected/p1.cpp @@ -0,0 +1,519 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test0 { + class A { + protected: int x; // expected-note 3 {{declared}} \ + // expected-note {{member is declared here}} + static int sx; // expected-note 3 {{declared}} \ + // expected-note {{member is declared here}} + }; + class B : public A { + }; + class C : protected A { // expected-note {{declared}} + }; + class D : private B { // expected-note 3 {{constrained}} + }; + + void test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; // expected-error {{'sx' is a protected member}} + } + void test(B &b) { + (void) b.x; // expected-error {{'x' is a protected member}} + (void) b.sx; // expected-error {{'sx' is a protected member}} + } + void test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } + void test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } +} + +namespace test1 { + class A { + protected: int x; + static int sx; + static void test(A&); + }; + class B : public A { + static void test(B&); + }; + class C : protected A { + static void test(C&); + }; + class D : private B { + static void test(D&); + }; + + void A::test(A &a) { + (void) a.x; + (void) a.sx; + } + void B::test(B &b) { + (void) b.x; + (void) b.sx; + } + void C::test(C &c) { + (void) c.x; + (void) c.sx; + } + void D::test(D &d) { + (void) d.x; + (void) d.sx; + } +} + +namespace test2 { + class A { + protected: int x; // expected-note 3 {{can only access this member on an object of type}} + static int sx; + static void test(A&); + }; + class B : public A { + static void test(A&); + }; + class C : protected A { + static void test(A&); + }; + class D : private B { + static void test(A&); + }; + + void A::test(A &a) { + (void) a.x; + (void) a.sx; + } + void B::test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; + } + void C::test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; + } + void D::test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; + } +} + +namespace test3 { + class B; + class A { + protected: int x; //expected-note {{declared protected}} // expected-note {{can only access this member on an object of type}} + static int sx; + static void test(B&); + }; + class B : public A { + static void test(B&); + }; + class C : protected A { + static void test(B&); + }; + class D : private B { + static void test(B&); + }; + + void A::test(B &b) { + (void) b.x; + (void) b.sx; + } + void B::test(B &b) { + (void) b.x; + (void) b.sx; + } + void C::test(B &b) { + (void) b.x; // expected-error {{'x' is a protected member}} + (void) b.sx; + } + void D::test(B &b) { + (void) b.x; // expected-error {{'x' is a protected member}} + (void) b.sx; + } +} + +namespace test4 { + class C; + class A { + protected: int x; // expected-note 2{{declared protected here}} expected-note{{member is declared here}} + static int sx; // expected-note 3{{member is declared here}} + static void test(C&); + }; + class B : public A { + static void test(C&); + }; + class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}} + static void test(C&); + }; + class D : private B { + static void test(C&); + }; + + void A::test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} \ + // expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } + void B::test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} \ + // expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } + void C::test(C &c) { + (void) c.x; + (void) c.sx; + } + void D::test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} \ + // expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } +} + +namespace test5 { + class D; + class A { + protected: int x; // expected-note 3{{member is declared here}} + static int sx; // expected-note 3{{member is declared here}} + static void test(D&); + }; + class B : public A { + static void test(D&); + }; + class C : protected A { + static void test(D&); + }; + class D : private B { // expected-note 9 {{constrained}} + static void test(D&); + }; + + void A::test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} \ + // expected-error {{cannot cast}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } + void B::test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} \ + // expected-error {{cannot cast}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } + void C::test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} \ + // expected-error {{cannot cast}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } + void D::test(D &d) { + (void) d.x; + (void) d.sx; + } +} + +namespace test6 { + class Static {}; + class A { + protected: + void foo(int); // expected-note 3 {{can only access this member on an object of type}} + void foo(long); + static void foo(Static); + + static void test(A&); + }; + class B : public A { + static void test(A&); + }; + class C : protected A { + static void test(A&); + }; + class D : private B { + static void test(A&); + }; + + void A::test(A &a) { + a.foo(10); + a.foo(Static()); + } + void B::test(A &a) { + a.foo(10); // expected-error {{'foo' is a protected member}} + a.foo(Static()); + } + void C::test(A &a) { + a.foo(10); // expected-error {{'foo' is a protected member}} + a.foo(Static()); + } + void D::test(A &a) { + a.foo(10); // expected-error {{'foo' is a protected member}} + a.foo(Static()); + } +} + +namespace test7 { + class Static {}; + class A { + protected: + void foo(int); // expected-note 3 {{must name member using the type of the current context}} + void foo(long); + static void foo(Static); + + static void test(); + }; + class B : public A { + static void test(); + }; + class C : protected A { + static void test(); + }; + class D : private B { + static void test(); + }; + + void A::test() { + void (A::*x)(int) = &A::foo; + void (*sx)(Static) = &A::foo; + } + void B::test() { + void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} + void (*sx)(Static) = &A::foo; + } + void C::test() { + void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} + void (*sx)(Static) = &A::foo; + } + void D::test() { + void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} + void (*sx)(Static) = &A::foo; + } +} + +namespace test8 { + class Static {}; + class A { + protected: + void foo(int); // expected-note 3 {{must name member using the type of the current context}} + void foo(long); + static void foo(Static); + + static void test(); + }; + class B : public A { + static void test(); + }; + class C : protected A { + static void test(); + }; + class D : private B { + static void test(); + }; + void call(void (A::*)(int)); + void calls(void (*)(Static)); + + void A::test() { + call(&A::foo); + calls(&A::foo); + } + void B::test() { + call(&A::foo); // expected-error {{'foo' is a protected member}} + calls(&A::foo); + } + void C::test() { + call(&A::foo); // expected-error {{'foo' is a protected member}} + calls(&A::foo); + } + void D::test() { + call(&A::foo); // expected-error {{'foo' is a protected member}} + calls(&A::foo); + } +} + +namespace test9 { + class A { // expected-note {{member is declared here}} + protected: int foo(); // expected-note 4 {{declared}} expected-note 2 {{can only access this member on an object of type}} expected-note {{member is declared here}} + }; + + class B : public A { // expected-note {{member is declared here}} + friend class D; + }; + + class C : protected B { // expected-note {{declared}} \ + // expected-note 9 {{constrained}} + }; + + class D : public A { + static void test(A &a) { + a.foo(); // expected-error {{'foo' is a protected member}} + a.A::foo(); // expected-error {{'foo' is a protected member}} + a.B::foo(); + a.C::foo(); // expected-error {{'foo' is a protected member}} + } + + static void test(B &b) { + b.foo(); + b.A::foo(); + b.B::foo(); + b.C::foo(); // expected-error {{'foo' is a protected member}} + } + + static void test(C &c) { + c.foo(); // expected-error {{'foo' is a protected member}} \ + // expected-error {{cannot cast}} + c.A::foo(); // expected-error {{'A' is a protected member}} \ + // expected-error {{cannot cast}} + c.B::foo(); // expected-error {{'B' is a protected member}} \ + // expected-error {{cannot cast}} + c.C::foo(); // expected-error {{'foo' is a protected member}} \ + // expected-error {{cannot cast}} + } + + static void test(D &d) { + d.foo(); + d.A::foo(); + d.B::foo(); + d.C::foo(); // expected-error {{'foo' is a protected member}} + } + }; +} + +namespace test10 { + template class A { + protected: + int foo(); + int foo() const; + + ~A() { foo(); } + }; + + template class A; +} + +// rdar://problem/8360285: class.protected friendship +namespace test11 { + class A { + protected: + int foo(); + }; + + class B : public A { + friend class C; + }; + + class C { + void test() { + B b; + b.A::foo(); + } + }; +} + +// This friendship is considered because a public member of A would be +// a private member of C. +namespace test12 { + class A { protected: int foo(); }; + class B : public virtual A {}; + class C : private B { friend void test(); }; + class D : private C, public virtual A {}; + + void test() { + D d; + d.A::foo(); + } +} + +// This friendship is not considered because a public member of A is +// inaccessible in C. +namespace test13 { + class A { protected: int foo(); }; // expected-note {{can only access this member on an object of type}} + class B : private virtual A {}; + class C : private B { friend void test(); }; + class D : public virtual A {}; + + void test() { + D d; + d.A::foo(); // expected-error {{protected member}} + } +} + +// PR8058 +namespace test14 { + class A { + protected: + template void temp(T t); // expected-note {{must name member using the type of the current context}} + + void nontemp(int); // expected-note {{must name member using the type of the current context}} + + template void ovl_temp(T t); // expected-note {{must name member using the type of the current context}} + void ovl_temp(float); + + void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}} + void ovl_nontemp(float); + + template void ovl_withtemp(T); + void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}} + }; + + class B : public A { + void use() { + void (A::*ptr)(int); + ptr = &A::temp; // expected-error {{protected member}} + ptr = &A::nontemp; // expected-error {{protected member}} + ptr = &A::ovl_temp; // expected-error {{protected member}} + ptr = &A::ovl_nontemp; // expected-error {{protected member}} + ptr = &A::ovl_withtemp; // expected-error {{protected member}} + } + }; +} + +namespace test15 { + class A { + protected: + A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}} + A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}} + ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}} + }; + + class B : public A { + // The uses here are fine. + B() {} + B(int i) : A() {} + ~B() {} + + // All these uses are bad. + + void test0() { + A a; // expected-error {{protected constructor}} expected-error {{protected destructor}} + } + + A *test1() { + return new A(); // expected-error {{protected constructor}} + } + + void test2(A *a) { + delete a; // expected-error {{protected destructor}} + } + + A test3(A *a) { + return *a; // expected-error {{protected constructor}} + } + + void test4(A *a) { + a->~A(); // expected-error {{protected member}} + } + }; +} + +namespace test16 { + class A { + protected: + ~A(); + }; + + class B : public virtual A { + public: + ~B() {} + }; + + class C : public B { + ~C() {} + }; +} diff --git a/clang/test/CXX/class.access/p4.cpp b/clang/test/CXX/class.access/p4.cpp new file mode 100644 index 0000000..5ad738b --- /dev/null +++ b/clang/test/CXX/class.access/p4.cpp @@ -0,0 +1,510 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s + +// C++0x [class.access]p4: + +// Access control is applied uniformly to all names, whether the +// names are referred to from declarations or expressions. In the +// case of overloaded function names, access control is applied to +// the function selected by overload resolution. + +class Public {} PublicInst; +class Protected {} ProtectedInst; +class Private {} PrivateInst; + +namespace test0 { + class A { + public: + void foo(Public&); + protected: + void foo(Protected&); // expected-note 2 {{declared protected here}} + private: + void foo(Private&); // expected-note 2 {{declared private here}} + }; + + void test(A *op) { + op->foo(PublicInst); + op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}} + op->foo(PrivateInst); // expected-error {{'foo' is a private member}} + + void (A::*a)(Public&) = &A::foo; + void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}} + void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}} + } +} + +// Member operators. +namespace test1 { + class A { + public: + void operator+(Public&); + void operator[](Public&); + void operator()(Public&); + typedef void (*PublicSurrogate)(Public&); + operator PublicSurrogate() const; + protected: + void operator+(Protected&); // expected-note {{declared protected here}} + void operator[](Protected&); // expected-note {{declared protected here}} + void operator()(Protected&); // expected-note {{declared protected here}} + typedef void (*ProtectedSurrogate)(Protected&); + operator ProtectedSurrogate() const; // expected-note {{declared protected here}} + private: + void operator+(Private&); // expected-note {{declared private here}} + void operator[](Private&); // expected-note {{declared private here}} + void operator()(Private&); // expected-note {{declared private here}} + void operator-(); // expected-note {{declared private here}} + typedef void (*PrivateSurrogate)(Private&); + operator PrivateSurrogate() const; // expected-note {{declared private here}} + }; + void operator+(const A &, Public&); + void operator+(const A &, Protected&); + void operator+(const A &, Private&); + void operator-(const A &); + + void test(A &a, Public &pub, Protected &prot, Private &priv) { + a + pub; + a + prot; // expected-error {{'operator+' is a protected member}} + a + priv; // expected-error {{'operator+' is a private member}} + a[pub]; + a[prot]; // expected-error {{'operator[]' is a protected member}} + a[priv]; // expected-error {{'operator[]' is a private member}} + a(pub); + a(prot); // expected-error {{'operator()' is a protected member}} + a(priv); // expected-error {{'operator()' is a private member}} + -a; // expected-error {{'operator-' is a private member}} + + const A &ca = a; + ca + pub; + ca + prot; + ca + priv; + -ca; + // These are all surrogate calls + ca(pub); + ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}} + ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}} + } +} + +// Implicit constructor calls. +namespace test2 { + class A { + private: + A(); // expected-note 3 {{declared private here}} + + static A foo; + }; + + A a; // expected-error {{calling a private constructor}} + A A::foo; // okay + + class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}} + B b; // expected-note{{implicit default constructor}} + + class C : virtual A { + public: + C(); + }; + + class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private default constructor}} + D d; // expected-note{{implicit default constructor}} +} + +// Implicit destructor calls. +namespace test3 { + class A { + private: + ~A(); // expected-note 2 {{declared private here}} + static A foo; + }; + + A a; // expected-error {{variable of type 'test3::A' has private destructor}} + A A::foo; + + void foo(A param) { // okay + A local; // expected-error {{variable of type 'test3::A' has private destructor}} + } + + template class Base { ~Base(); }; // expected-note 14 {{declared private here}} + class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \ + // expected-error {{base class 'Base<2>' has private destructor}} + class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}} + + // These don't cause diagnostics because we don't need the destructor. + class Derived0 : Base<0> { ~Derived0(); }; + class Derived1 : Base<1> { }; + + class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \ + // expected-error {{inherited virtual base class 'Base<3>' has private destructor}} + Base<0>, // expected-error {{base class 'Base<0>' has private destructor}} + virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}} + Base2, // expected-error {{base class 'test3::Base2' has private destructor}} + virtual Base3 + { + ~Derived2() {} + }; + + class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \ + // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}} \ + // expected-note 2{{implicit default constructor}} + Base<0>, // expected-error 2 {{base class 'Base<0>' has private destructor}} + virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}} + Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}} + virtual Base3 + {}; + Derived3 d3; // expected-note {{implicit default constructor}}\ + // expected-note{{implicit default destructor}}} +} + +// Conversion functions. +namespace test4 { + class Base { + private: + operator Private(); // expected-note 4 {{declared private here}} + public: + operator Public(); // expected-note 2{{member is declared here}} + }; + + class Derived1 : private Base { // expected-note 2 {{declared private here}} \ + // expected-note {{constrained by private inheritance}} + Private test1() { return *this; } // expected-error {{'operator Private' is a private member}} + Public test2() { return *this; } + }; + Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \ + // expected-error {{cannot cast 'test4::Derived1' to its private base class}} + Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \ + // expected-error {{'operator Public' is a private member}} + + + class Derived2 : public Base { + Private test1() { return *this; } // expected-error {{'operator Private' is a private member}} + Public test2() { return *this; } + }; + Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}} + Public test2(Derived2 &d) { return d; } + + class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \ + // expected-note {{declared private here}} + public: + operator Private(); + }; + Private test1(Derived3 &d) { return d; } + Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \ + // expected-error {{cannot cast 'test4::Derived3' to its private base class}} + + class Derived4 : public Base { + public: + operator Private(); + }; + Private test1(Derived4 &d) { return d; } + Public test2(Derived4 &d) { return d; } +} + +// Implicit copy assignment operator uses. +namespace test5 { + class A { + void operator=(const A &); // expected-note 2 {{implicitly declared private here}} + }; + + class Test1 { A a; }; // expected-error {{private member}} + void test1() { + Test1 a; + a = Test1(); // expected-note{{implicit default copy}} + } + + class Test2 : A {}; // expected-error {{private member}} + void test2() { + Test2 a; + a = Test2(); // expected-note{{implicit default copy}} + } +} + +// Implicit copy constructor uses. +namespace test6 { + class A { + public: A(); + private: A(const A &); // expected-note 2 {{declared private here}} + }; + + class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}} + void test1(const Test1 &t) { + Test1 a = t; // expected-note{{implicit default copy}} + } + + class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}} + void test2(const Test2 &t) { + Test2 a = t; // expected-note{{implicit default copy}} + } +} + +// Redeclaration lookups are not accesses. +namespace test7 { + class A { + int private_member; + }; + class B : A { + int foo(int private_member) { + return 0; + } + }; +} + +// Ignored operator new and delete overloads are not +namespace test8 { + typedef __typeof__(sizeof(int)) size_t; + + class A { + void *operator new(size_t s); + void operator delete(void *p); + public: + void *operator new(size_t s, int n); + void operator delete(void *p, int n); + }; + + void test() { + new (2) A(); + } +} + +// Don't silently upgrade forbidden-access paths to private. +namespace test9 { + class A { + public: static int x; // expected-note {{member is declared here}} + }; + class B : private A { // expected-note {{constrained by private inheritance here}} + }; + class C : public B { + static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}} + }; +} + +namespace test10 { + class A { + enum { + value = 10 // expected-note {{declared private here}} + }; + friend class C; + }; + + class B { + enum { + value = A::value // expected-error {{'value' is a private member of 'test10::A'}} + }; + }; + + class C { + enum { + value = A::value + }; + }; +} + +namespace test11 { + class A { + protected: virtual ~A(); + }; + + class B : public A { + ~B(); + }; + + B::~B() {}; +} + +namespace test12 { + class A { + int x; + + void foo() { + class Local { + int foo(A *a) { + return a->x; + } + }; + } + }; +} + +namespace test13 { + struct A { + int x; + unsigned foo() const; + }; + + struct B : protected A { + using A::foo; + using A::x; + }; + + void test() { + A *d; + d->foo(); + (void) d->x; + } +} + +// Destructors for temporaries. +namespace test14 { + class A { + private: ~A(); // expected-note {{declared private here}} + }; + A foo(); + + void test() { + foo(); // expected-error {{temporary of type 'test14::A' has private destructor}} + } + + class X { + ~X(); // expected-note {{declared private here}} + }; + + struct Y1 { + operator X(); + }; + + void g() { + const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}} + } +} + +// PR 7024 +namespace test15 { + template class A { + private: + int private_foo; // expected-note {{declared private here}} + static int private_sfoo; // expected-note {{declared private here}} + protected: + int protected_foo; // expected-note 3 {{declared protected here}} // expected-note {{can only access this member on an object of type 'test15::B'}} + static int protected_sfoo; // expected-note 3 {{declared protected here}} + + int test1(A &a) { + return a.private_foo; // expected-error {{private member}} + } + + int test2(A &a) { + return a.private_sfoo; // expected-error {{private member}} + } + + int test3(A &a) { + return a.protected_foo; // expected-error {{protected member}} + } + + int test4(A &a) { + return a.protected_sfoo; // expected-error {{protected member}} + } + }; + + template class A; + template class A; // expected-note 4 {{in instantiation}} + + template class B : public A { + // TODO: These first two accesses can be detected as ill-formed at + // definition time because they're member accesses and A can't + // be a subclass of B for any T. + + int test1(A &a) { + return a.protected_foo; // expected-error 2 {{protected member}} + } + + int test2(A &a) { + return a.protected_sfoo; // expected-error {{protected member}} + } + + int test3(B &b) { + return b.protected_foo; // expected-error {{protected member}} + } + + int test4(B &b) { + return b.protected_sfoo; // expected-error {{protected member}} + } + }; + + template class B; // expected-note {{in instantiation}} + template class B; // expected-note 4 {{in instantiation}} +} + +// PR7281 +namespace test16 { + class A { ~A(); }; // expected-note 2{{declared private here}} + void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \ + // expected-error{{exception object of type 'test16::A' has private destructor}} +} + +// rdar://problem/8146294 +namespace test17 { + class A { + template class Inner { }; // expected-note {{declared private here}} + }; + + A::Inner s; // expected-error {{'Inner' is a private member of 'test17::A'}} +} + +namespace test18 { + template class A {}; + class B : A { + A member; + }; + + // FIXME: this access to A should be forbidden (because C++ is dumb), + // but LookupResult can't express the necessary information to do + // the check, so we aggressively suppress access control. + class C : B { + A member; + }; +} + +// PR8325 +namespace test19 { + class A { ~A(); }; + // The destructor is not implicitly referenced here. Contrast to test16, + // testing PR7281, earlier in this file. + void b(A* x) { throw x; } +} + +// PR7930 +namespace test20 { + class Foo { + Foo(); // expected-note {{implicitly declared private here}} + }; + Foo::Foo() {} + + void test() { + Foo a; // expected-error {{calling a private constructor}} + } +} + +namespace test21 { + template class A { + void foo(); + void bar(); + class Inner; // expected-note {{implicitly declared private here}} + public: + void baz(); + }; + template class A::Inner {}; + class B { + template class A::Inner; // expected-error{{non-friend class member 'Inner' cannot have a qualified name}} + }; + + void test() { + A::Inner i; // expected-error {{'Inner' is a private member}} + } +} + +namespace rdar8876150 { + struct A { operator bool(); }; + struct B : private A { using A::operator bool; }; + + bool f() { + B b; + return !b; + } +} + +namespace test23 { + template class A { + A(); + static A instance; + }; + + template A A::instance; + template class A; +} diff --git a/clang/test/CXX/class.access/p6.cpp b/clang/test/CXX/class.access/p6.cpp new file mode 100644 index 0000000..fbdc87b --- /dev/null +++ b/clang/test/CXX/class.access/p6.cpp @@ -0,0 +1,192 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [class.access]p6: +// All access controls in [class.access] affect the ability to +// access a class member name from a particular scope. For purposes +// of access control, the base-specifiers of a class and the +// definitions of class members that appear outside of the class +// definition are considered to be within the scope of that +// class. In particular, access controls apply as usual to member +// names accessed as part of a function return type, even though it +// is not possible to determine the access privileges of that use +// without first parsing the rest of the function +// declarator. Similarly, access control for implicit calls to the +// constructors, the conversion functions, or the destructor called +// to create and destroy a static data member is performed as if +// these calls appeared in the scope of the member's class. + +struct Public {}; struct Protected {}; struct Private {}; + +namespace test0 { + class A { + typedef int type; // expected-note {{declared private here}} + type foo(); + }; + + A::type foo() { } // expected-error {{'type' is a private member}} + A::type A::foo() { } +} + +// conversion decls +namespace test1 { + class A { + public: + A(); + operator Public (); + A(Public); + protected: + operator Protected (); // expected-note {{declared protected here}} + A(Protected); // expected-note {{declared protected here}} + private: + operator Private (); // expected-note {{declared private here}} + A(Private); // expected-note {{declared private here}} + }; + + void test() { + A a; + Public pub = a; + Protected prot = a; // expected-error {{'operator Protected' is a protected member}} + Private priv = a; // expected-error {{'operator Private' is a private member}} + A apub = pub; + A aprot = prot; // expected-error {{protected constructor}} + A apriv = priv; // expected-error {{private constructor}} + } +} + +// PR6967 +namespace test2 { + class A { + public: + template static void set(T &t, typename T::type v) { + t.value = v; + } + template static typename T::type get(const T &t) { + return t.value; + } + }; + + class B { + friend class A; + + private: + typedef int type; + type value; + }; + + int test() { + B b; + A::set(b, 0); + return A::get(b); + } +} + +namespace test3 { + class Green {}; class Blue {}; + + // We have to wrap this in a class because a partial specialization + // isn't actually in the context of the template. + struct Outer { + template class A { + }; + }; + + template class Outer::A { + public: + static void foo(); + }; + + class B { + private: typedef Green nature; + friend class Outer; + }; + + void test() { + Outer::A::foo(); + Outer::A::foo(); // expected-error {{no member named 'foo'}} + } +} + +namespace test4 { + template class A { + private: typedef int type; + template friend void foo(U &, typename U::type); + }; + + template void foo(U &, typename U::type) {} + + void test() { + A a; + foo(a, 0); + } +} + +// PR7644 +namespace test5 { + class A { + enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}} + template void foo(); + template class bar; + }; + + template void A::foo() {} + template class A::bar {}; + + template void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}} + template class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}} + + class B { + template void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}} + template class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}} + }; +} + +namespace test6 { + class A { + public: class public_inner {}; + protected: class protected_inner {}; + private: class private_inner {}; // expected-note {{declared private here}} + }; + + class B : A { + public_inner a; + protected_inner b; + private_inner c; // expected-error {{'private_inner' is a private member of 'test6::A'}} + }; +} + +// PR9229 +namespace test7 { + void foo(int arg[1]); + class A { + void check(); + }; + class B { + friend class A; + A ins; + }; + void A::check() { + void foo(int arg[__builtin_offsetof(B, ins)]); + } +} + +// rdar://problem/10155256 +namespace test8 { + class A { + typedef void* (A::*UnspecifiedBoolType)() const; + operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}} + }; + + void test(A &a) { + if (a) return; // expected-error {{'operator void *(class test8::A::*)(void) const' is a private member of 'test8::A'}} + } +} + +namespace test9 { + class A { + operator char*() const; // expected-note {{implicitly declared private here}} + }; + + void test(A &a) { + delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}} + } +} diff --git a/clang/test/CXX/class.derived/class.abstract/p4.cpp b/clang/test/CXX/class.derived/class.abstract/p4.cpp new file mode 100644 index 0000000..b04de21 --- /dev/null +++ b/clang/test/CXX/class.derived/class.abstract/p4.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR6631 { + struct A { + virtual void f() = 0; + }; + + struct B : virtual A { }; + + struct C : virtual A { + virtual void f(); + }; + + struct D : public B, public C { + virtual void f(); + }; + + void f() { + (void)new D; // okay + } +} + +// Check cases where we have a virtual function that is pure in one +// subobject but not pure in another subobject. +namespace PartlyPure { + struct A { + virtual void f() = 0; // expected-note{{unimplemented pure virtual method}} + }; + + struct B : A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // expected-error{{abstract class}} + } +} + +namespace NonPureAlongOnePath { + struct A { + virtual void f() = 0; + }; + + struct B : virtual A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // okay + } +} + +namespace NonPureAlongOnePath2 { + struct Aprime { + virtual void f() = 0; + }; + + struct A : Aprime { + }; + + struct B : virtual A { + virtual void f(); + }; + + struct C : virtual A { }; + + struct D : B, C { }; + + void f() { + (void) new D; // okay + } +} diff --git a/clang/test/CXX/class.derived/class.abstract/p5.cpp b/clang/test/CXX/class.derived/class.abstract/p5.cpp new file mode 100644 index 0000000..cdff931 --- /dev/null +++ b/clang/test/CXX/class.derived/class.abstract/p5.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + virtual void f() = 0; // expected-note{{unimplemented pure virtual method}} +}; + +struct B : A { + virtual void f(); +}; + +struct C : B { + virtual void f() = 0; // expected-note 2{{unimplemented pure virtual method}} +}; + +struct D : C { +}; + +void test() { + (void)new A; // expected-error{{abstract class}} + (void)new B; + (void)new C; // expected-error{{abstract class}} + (void)new D; // expected-error{{abstract class}} +} diff --git a/clang/test/CXX/class.derived/class.member.lookup/p6.cpp b/clang/test/CXX/class.derived/class.member.lookup/p6.cpp new file mode 100644 index 0000000..7239881 --- /dev/null +++ b/clang/test/CXX/class.derived/class.member.lookup/p6.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class V { +public: + int f(); + int x; +}; + +class W { +public: + int g(); // expected-note{{member found by ambiguous name lookup}} + int y; // expected-note{{member found by ambiguous name lookup}} +}; + +class B : public virtual V, public W +{ +public: + int f(); + int x; + int g(); // expected-note{{member found by ambiguous name lookup}} + int y; // expected-note{{member found by ambiguous name lookup}} +}; + +class C : public virtual V, public W { }; + +class D : public B, public C { void glorp(); }; + +void D::glorp() { + x++; + f(); + y++; // expected-error{{member 'y' found in multiple base classes of different types}} + g(); // expected-error{{member 'g' found in multiple base classes of different types}} +} + +// PR6462 +struct BaseIO { BaseIO* rdbuf() { return 0; } }; +struct Pcommon : virtual BaseIO { int rdbuf() { return 0; } }; +struct P : virtual BaseIO, Pcommon {}; + +void f() { P p; p.rdbuf(); } diff --git a/clang/test/CXX/class.derived/class.member.lookup/p8.cpp b/clang/test/CXX/class.derived/class.member.lookup/p8.cpp new file mode 100644 index 0000000..4d4acc3 --- /dev/null +++ b/clang/test/CXX/class.derived/class.member.lookup/p8.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: Access control checks + +namespace PR5820 { + // also + struct Base { + void Foo(); + int Member; + }; + + struct D1 : public Base {}; + struct D2 : public Base {}; + + struct Derived : public D1, public D2 { + void Inner(); + }; + + void Test() { + Derived d; + d.D1::Foo(); + d.D1::Member = 17; + } + + void Derived::Inner() { + D1::Foo(); + D1::Member = 42; + this->D1::Foo(); + this->D1::Member = 42; + } +} + +template +struct BaseT { + void Foo(); // expected-note{{found by ambiguous name lookup}} + int Member; +}; + +template struct Derived1T : BaseT { }; +template struct Derived2T : BaseT { }; + +template +struct DerivedT : public Derived1T, public Derived2T { + void Inner(); +}; + +template +void DerivedT::Inner() { + Derived1T::Foo(); + Derived2T::Member = 42; + this->Derived1T::Foo(); + this->Derived2T::Member = 42; + this->Foo(); // expected-error{{non-static member 'Foo' found in multiple base-class subobjects of type 'BaseT'}} +} + +template +void Test(DerivedT d) { + d.template Derived1T::Foo(); + d.template Derived2T::Member = 17; + d.Inner(); // expected-note{{in instantiation}} +} + +template void Test(DerivedT); diff --git a/clang/test/CXX/class.derived/class.member.lookup/p9.cpp b/clang/test/CXX/class.derived/class.member.lookup/p9.cpp new file mode 100644 index 0000000..ba7bd21 --- /dev/null +++ b/clang/test/CXX/class.derived/class.member.lookup/p9.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace rdar8436162 { + class ClsA { + public: + static void f(); + void g(); + }; + + class ClsB : virtual private ClsA { + public: + using ClsA::f; + using ClsA::g; // expected-note{{member found by ambiguous name lookup}} + }; + + class ClsF : virtual private ClsA { + public: + using ClsA::f; + using ClsA::g; // expected-note{{member found by ambiguous name lookup}} + }; + + class ClsE : public ClsB, public ClsF { + void test() { + f(); + g(); // expected-error{{member 'g' found in multiple base classes of different types}} + } + }; +} diff --git a/clang/test/CXX/class.derived/class.virtual/p12.cpp b/clang/test/CXX/class.derived/class.virtual/p12.cpp new file mode 100644 index 0000000..208a0d1 --- /dev/null +++ b/clang/test/CXX/class.derived/class.virtual/p12.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -ast-print %s | FileCheck %s + +// CHECK: test12_A::foo() +struct test12_A { + virtual void foo(); + + void bar() { + test12_A::foo(); + } +}; + +// CHECK: xp->test24_B::wibble() +struct test24_B { + virtual void wibble(); +}; + +void foo(test24_B *xp) { + xp->test24_B::wibble(); +} diff --git a/clang/test/CXX/class.derived/class.virtual/p2.cpp b/clang/test/CXX/class.derived/class.virtual/p2.cpp new file mode 100644 index 0000000..64d93c8 --- /dev/null +++ b/clang/test/CXX/class.derived/class.virtual/p2.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A { + virtual void f() = 0; // expected-note 2{{overridden virtual function}} +}; + +struct Aprime : virtual A { + virtual void f(); +}; + +struct B : Aprime { + virtual void f(); // expected-note 3{{final overrider of 'A::f'}} +}; + +struct C : virtual A { + virtual void f(); // expected-note{{final overrider of 'A::f'}} +}; + +struct D : B, C { }; // expected-error{{virtual function 'A::f' has more than one final overrider in 'D'}} + +struct B2 : B { }; + +struct E : B, B2 { }; //expected-error{{virtual function 'A::f' has more than one final overrider in 'E'}} + +struct F : B, B2 { + virtual void f(); // okay +}; + +struct G : F { }; // okay + +struct H : G, A { }; // okay + +namespace MultipleSubobjects { + struct A { virtual void f(); }; + struct B : A { virtual void f(); }; + struct C : A { virtual void f(); }; + struct D : B, C { }; // okay +} diff --git a/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp b/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp new file mode 100644 index 0000000..c4a401b --- /dev/null +++ b/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +namespace Test1 { + +struct B { + virtual void f(int); +}; + +struct D : B { + virtual void f(long) override; // expected-error {{'f' marked 'override' but does not override any member functions}} + void f(int) override; +}; +} + +namespace Test2 { + +struct A { + virtual void f(int, char, int); +}; + +template +struct B : A { + virtual void f(T) override; +}; + +} + +namespace Test3 { + +struct A { + virtual void f(int, char, int); +}; + +template +struct B : A { + virtual void f(Args...) override; // expected-error {{'f' marked 'override' but does not override any member functions}} +}; + +template struct B; +template struct B; // expected-note {{in instantiation of template class 'Test3::B' requested here}} + +} + +namespace Test4 { +struct B { + virtual void f() const final; // expected-note {{overridden virtual function is here}} +}; + +struct D : B { + void f() const; // expected-error {{declaration of 'f' overrides a 'final' function}} +}; + +} diff --git a/clang/test/CXX/class.derived/p1.cpp b/clang/test/CXX/class.derived/p1.cpp new file mode 100644 index 0000000..dc5cb2b --- /dev/null +++ b/clang/test/CXX/class.derived/p1.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11 + +// base-clause: +// : base-specifier-list +// base-specifier-list: +// base-specifier ...[opt] +// base-specifier-list , base-specifier ...[opt] +// base-specifier: +// attribute-specifier-seq[opt] base-type-specifier +// attribute-specifier-seq[opt] virtual access-specifier[opt] base-type-specifier +// attribute-specifier-seq[opt] access-specifier virtual[opt] base-type-specifier +// class-or-decltype: +// nested-name-specifier[opt] class-name +// decltype-specifier +// base-type-specifier: +// class-or-decltype +// access-specifier: +// private +// protected +// public + +namespace PR11216 { + struct Base { }; + struct Derived : decltype(Base()) { }; + + int func(); + struct Derived2 : decltype(func()) { }; // expected-error {{base specifier must name a class}} + + template + struct Derived3 : decltype(T().foo()) { }; + struct Foo { Base foo(); }; + Derived3 d; + + struct Derived4 : :: decltype(Base()) { }; // expected-error {{unexpected namespace scope prior to decltype}} + + struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{unexpected namespace scope prior to decltype}} + + template + struct Derived6 : typename T::foo { }; // expected-error {{'typename' is redundant; base classes are implicitly types}} +} diff --git a/clang/test/CXX/class.derived/p2.cpp b/clang/test/CXX/class.derived/p2.cpp new file mode 100644 index 0000000..7ef53d3 --- /dev/null +++ b/clang/test/CXX/class.derived/p2.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify + +// "During the lookup for a base class name, non-type names are ignored" +namespace PR5840 { + struct Base {}; + int Base = 10; + struct Derived : Base {}; +} diff --git a/clang/test/CXX/class/class.base/class.base.init/p5-0x.cpp b/clang/test/CXX/class/class.base/class.base.init/p5-0x.cpp new file mode 100644 index 0000000..e9aa6da --- /dev/null +++ b/clang/test/CXX/class/class.base/class.base.init/p5-0x.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// [class.base.init]p5 +// A ctor-initializer may initialize a variant member of the constructor’s +// class. If a ctor-initializer specifies more than one mem-initializer for the +// same member or for the same base class, the ctor-initializer is ill-formed. + +union E { + int a; + int b; + E() : a(1), // expected-note{{previous initialization is here}} + b(2) { // expected-error{{initializing multiple members of union}} + } +}; + +union F { + struct { + int a; + int b; + }; + int c; + F() : a(1), // expected-note{{previous initialization is here}} + b(2), + c(3) { // expected-error{{initializing multiple members of union}} + } +}; diff --git a/clang/test/CXX/class/class.bit/p2.cpp b/clang/test/CXX/class/class.bit/p2.cpp new file mode 100644 index 0000000..7962330 --- /dev/null +++ b/clang/test/CXX/class/class.bit/p2.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct A { +private: + int : 0; +}; + +A a = { }; +A a2 = { 1 }; // expected-error{{excess elements in struct initializer}} + +struct B { + const int : 0; +}; + +B b; + +void testB() { + B b2(b); + B b3(static_cast(b2)); + b = b; + b = static_cast(b); +} diff --git a/clang/test/CXX/class/class.friend/p1-ambiguous.cpp b/clang/test/CXX/class/class.friend/p1-ambiguous.cpp new file mode 100644 index 0000000..a9dca4f --- /dev/null +++ b/clang/test/CXX/class/class.friend/p1-ambiguous.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Make sure that friend declarations don't introduce ambiguous +// declarations. + +// Test case courtesy of Shantonu Sen. +// Bug 4784. + +class foo; + +extern "C" { + int c_func(foo *a); +}; +int cpp_func(foo *a); + +class foo { +public: + friend int c_func(foo *a); + friend int cpp_func(foo *a); + int caller(); +private: + int x; +}; + +int c_func(foo *a) { + return a->x; +} + +int cpp_func(foo *a) { + return a->x; +} + +int foo::caller() { + c_func(this); + cpp_func(this); + return 0; +} diff --git a/clang/test/CXX/class/class.friend/p1-cxx11.cpp b/clang/test/CXX/class/class.friend/p1-cxx11.cpp new file mode 100644 index 0000000..235f295 --- /dev/null +++ b/clang/test/CXX/class/class.friend/p1-cxx11.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +class A { + class AInner { + }; + + void a_member(); + friend void A::a_member(); // ok in c++11, ill-formed in c++98 + friend void a_member(); // ok in both, refers to non-member + friend class A::AInner; // ok in c++11, extension in c++98 + friend class AInner; // ok in both, refers to non-member +}; diff --git a/clang/test/CXX/class/class.friend/p1.cpp b/clang/test/CXX/class/class.friend/p1.cpp new file mode 100644 index 0000000..07b3a10 --- /dev/null +++ b/clang/test/CXX/class/class.friend/p1.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct Outer { + struct Inner { + int intfield; + }; +}; + +struct Base { + void base_member(); + + typedef int Int; + Int typedeffed_member(); +}; + +struct Derived : public Base { +}; + +int myglobal; + +void global_function(); +extern "C" { + void global_c_function(); +} + +class A { + class AInner { + }; + + friend class PreDeclared; + friend class Outer::Inner; + friend int Outer::Inner::intfield; // expected-error {{friends can only be classes or functions}} + friend int Outer::Inner::missing_field; //expected-error {{friends can only be classes or functions}} + friend int myoperation(float); // okay + friend int myglobal; // expected-error {{friends can only be classes or functions}} + + friend void global_function(); + friend void global_c_function(); + + friend class UndeclaredSoFar; + UndeclaredSoFar x; // expected-error {{unknown type name 'UndeclaredSoFar'}} + + void a_member(); + friend void A::a_member(); // expected-error {{friends cannot be members of the declaring class}} + friend void a_member(); // okay (because we ignore class scopes when looking up friends) + friend class A::AInner; // this is okay as an extension + friend class AInner; // okay, refers to ::AInner + + friend void Derived::missing_member(); // expected-error {{no function named 'missing_member' with type 'void ()' was found in the specified scope}} + + friend void Derived::base_member(); // expected-error {{no function named 'base_member' with type 'void ()' was found in the specified scope}} + + friend int Base::typedeffed_member(); // okay: should look through typedef + + // These test that the friend is properly not being treated as a + // member function. + friend A operator|(const A& l, const A& r); // okay + friend A operator|(const A& r); // expected-error {{overloaded 'operator|' must be a binary operator (has 1 parameter)}} + + friend operator bool() const; // expected-error {{must use a qualified name when declaring a conversion operator as a friend}} \ + // expected-error{{non-member function cannot have 'const' qualifier}} + + typedef void ftypedef(); + friend ftypedef typedeffed_function; // okay (because it's not declared as a member) + + class facet; + friend class facet; // should not assert + class facet {}; +}; + +A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'A'}} + +class PreDeclared; + +int myoperation(float f) { + return (int) f; +} diff --git a/clang/test/CXX/class/class.friend/p2.cpp b/clang/test/CXX/class/class.friend/p2.cpp new file mode 100644 index 0000000..fb3cd19 --- /dev/null +++ b/clang/test/CXX/class/class.friend/p2.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct B0; + +class A { + friend class B {}; // expected-error {{cannot define a type in a friend declaration}} + friend int; // expected-warning {{non-class friend type 'int' is a C++11 extension}} + friend B0; // expected-warning {{specify 'struct' to befriend 'B0'}} + friend class C; // okay +}; diff --git a/clang/test/CXX/class/class.friend/p6.cpp b/clang/test/CXX/class/class.friend/p6.cpp new file mode 100644 index 0000000..7d7a064 --- /dev/null +++ b/clang/test/CXX/class/class.friend/p6.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify %s + +class A { + friend static class B; // expected-error {{'static' is invalid in friend declarations}} + friend extern class C; // expected-error {{'extern' is invalid in friend declarations}} + friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}} + friend register class E; // expected-error {{'register' is invalid in friend declarations}} + friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}} + friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}} +}; diff --git a/clang/test/CXX/class/class.local/p1-0x.cpp b/clang/test/CXX/class/class.local/p1-0x.cpp new file mode 100644 index 0000000..49125f5 --- /dev/null +++ b/clang/test/CXX/class/class.local/p1-0x.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +void f() { + int x = 3; // expected-note{{'x' declared here}} + const int c = 2; + struct C { + int& x2 = x; // expected-error{{reference to local variable 'x' declared in enclosing function 'f'}} + int cc = c; + }; + (void)[]() mutable { + int x = 3; // expected-note{{'x' declared here}} + struct C { + int& x2 = x; // expected-error{{reference to local variable 'x' declared in enclosing lambda expression}} + }; + }; + C(); +} + diff --git a/clang/test/CXX/class/class.local/p1.cpp b/clang/test/CXX/class/class.local/p1.cpp new file mode 100644 index 0000000..62ade5c --- /dev/null +++ b/clang/test/CXX/class/class.local/p1.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int x; +void f() +{ + static int s; + int x; // expected-note{{'x' declared here}} + extern int g(); + + struct local { + int g() { return x; } // expected-error{{reference to local variable 'x' declared in enclosing function 'f'}} + int h() { return s; } + int k() { return :: x; } + int l() { return g(); } + }; +} + +local* p = 0; // expected-error{{unknown type name 'local'}} diff --git a/clang/test/CXX/class/class.local/p2.cpp b/clang/test/CXX/class/class.local/p2.cpp new file mode 100644 index 0000000..db4c90f --- /dev/null +++ b/clang/test/CXX/class/class.local/p2.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { }; + +void f() { + struct B : private A {}; // expected-note{{declared private here}} + + B b; + + A *a = &b; // expected-error{{cannot cast 'B' to its private base class 'A'}} +} diff --git a/clang/test/CXX/class/class.local/p3.cpp b/clang/test/CXX/class/class.local/p3.cpp new file mode 100644 index 0000000..3753790 --- /dev/null +++ b/clang/test/CXX/class/class.local/p3.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f1() { + struct X { + struct Y; + }; + + struct X::Y { + void f() {} + }; +} + +void f2() { + struct X { + struct Y; + + struct Y { + void f() {} + }; + }; +} + +// A class nested within a local class is a local class. +void f3(int a) { // expected-note{{'a' declared here}} + struct X { + struct Y { + int f() { return a; } // expected-error{{reference to local variable 'a' declared in enclosing function 'f3'}} + }; + }; +} diff --git a/clang/test/CXX/class/class.local/p4.cpp b/clang/test/CXX/class/class.local/p4.cpp new file mode 100644 index 0000000..d780744 --- /dev/null +++ b/clang/test/CXX/class/class.local/p4.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f() { + struct X { + static int a; // expected-error {{static data member 'a' not allowed in local class 'X'}} + int b; + + static void f() { } + }; +} diff --git a/clang/test/CXX/class/class.mem/p1.cpp b/clang/test/CXX/class/class.mem/p1.cpp new file mode 100644 index 0000000..a41f1db --- /dev/null +++ b/clang/test/CXX/class/class.mem/p1.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct S +{ + static int v1; // expected-note{{previous declaration is here}} + int v1; //expected-error{{duplicate member 'v1'}} + int v; //expected-note 2{{previous definition is here}} \ + // expected-note{{previous declaration is here}} + static int v; //expected-error{{redefinition of 'v' as different kind of symbol}} + int v; //expected-error{{duplicate member 'v'}} + static int v; //expected-error{{redefinition of 'v' as different kind of symbol}} + enum EnumT { E = 10 }; + friend struct M; + struct X; //expected-note{{forward declaration of 'S::X'}} + friend struct X; +}; + +S::EnumT Evar = S::E; // ok +S::EnumT Evar2 = EnumT(); //expected-error{{use of undeclared identifier 'EnumT'}} +S::M m; //expected-error{{no type named 'M' in 'S'}} +S::X x; //expected-error{{variable has incomplete type 'S::X'}} + + +struct S2 +{ + static int v2; // expected-note{{previous declaration is here}} + static int v2; //expected-error{{duplicate member 'v2'}} +}; + +struct S3 +{ + static int v3; + struct S4 + { + static int v3; + }; +}; + +struct S4 +{ + static int v4; +}; + +int S4::v4; //expected-note{{previous definition is here}} +int S4::v4; //expected-error{{redefinition of 'v4'}} + +struct S5 +{ + static int v5; //expected-note{{previous definition is here}} + void v5() { } //expected-error{{redefinition of 'v5' as different kind of symbol}} + + void v6() { } //expected-note{{previous definition is here}} + static int v6; //expected-error{{redefinition of 'v6' as different kind of symbol}} + + void v7() { } + void v7(int) { } //expected-note{{previous definition is here}} + static int v7; //expected-error{{redefinition of 'v7' as different kind of symbol}} + + void v8(); + int v8(int); //expected-note{{previous declaration is here}} + int v8; //expected-error{{duplicate member 'v8'}} + + +}; + +namespace PR8245 { + class X { + public: + template + class Inner { + public: + void foo(bool bar = true); + int bam; + }; + + Inner _foo; + }; + + void f() { + X::Inner c2i; + X::Inner c2f; + c2i.foo(); + c2f.foo(); + } + + class Y { + class Inner { + void foo(int = sizeof(Y)); + }; + }; +} diff --git a/clang/test/CXX/class/class.mem/p13.cpp b/clang/test/CXX/class/class.mem/p13.cpp new file mode 100644 index 0000000..8488584 --- /dev/null +++ b/clang/test/CXX/class/class.mem/p13.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// If T is the name of a class, then each of the following shall have +// a name different from T: + +// - every static data member of class T; +struct X0 { + static int X0; // expected-error{{member 'X0' has the same name as its class}} +}; + +// - every member function of class T +// (Cannot be tested) + +// - every member of class T that is itself a type; +struct X1 { // expected-note{{previous use is here}} + enum X1 { }; // expected-error{{use of 'X1' with tag type that does not match previous declaration}} +}; + +struct X2 { + typedef int X2; // expected-error{{member 'X2' has the same name as its class}} +}; + +// - every enumerator of every member of class T that is an enumerated type; and +struct X3 { + enum E { + X3 // expected-error{{member 'X3' has the same name as its class}} + }; +}; + +// - every member of every anonymous union that is a member of class T. +struct X4 { + union { + int X; + union { + float Y; + unsigned X4; // expected-error{{member 'X4' has the same name as its class}} + }; + }; +}; + diff --git a/clang/test/CXX/class/class.mem/p14.cpp b/clang/test/CXX/class/class.mem/p14.cpp new file mode 100644 index 0000000..72b232e --- /dev/null +++ b/clang/test/CXX/class/class.mem/p14.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// In addition, if class T has a user-declared constructor (12.1), +// every non-static data member of class T shall have a name different +// from T. + +struct X0 { + int X0; // okay +}; + +struct X1 { + int X1; + X1(); // expected-error{{declarator requires an identifier}} +}; + +struct X2 { + X2(); + float X2; // expected-error{{member 'X2' has the same name as its class}} +}; diff --git a/clang/test/CXX/class/class.mem/p1b.cpp b/clang/test/CXX/class/class.mem/p1b.cpp new file mode 100644 index 0000000..3e8c985 --- /dev/null +++ b/clang/test/CXX/class/class.mem/p1b.cpp @@ -0,0 +1,46 @@ +// The first run checks that the correct errors are generated, +// implicitly checking the order of default argument parsing: +// RUN: %clang_cc1 -fsyntax-only -verify %s +// The second run checks the order of inline method definitions: +// RUN: not %clang_cc1 -fsyntax-only %s 2> %t +// RUN: FileCheck %s < %t + +class A { +public: + void a1() { + B b = B(); + } + + class B; + void a2(B b = B()); // expected-error{{use of default argument to function 'B' that is declared later in class 'B'}} + + void a3(int a = 42); + + // CHECK: error: use of undeclared identifier 'first' + void a4(int a = first); // expected-error{{use of undeclared identifier 'first'}} + + class B { + public: + B(int b = 42) { // expected-note{{default argument declared here}} + A a; + a.a3(); + a.a6(); + } + + void b1(A a = A()); // expected-error{{use of default argument to function 'A' that is declared later in class 'A'}} + + // CHECK: error: use of undeclared identifier 'second' + void b2(int a = second); // expected-error{{use of undeclared identifier 'second'}} + }; + + void a5() { + B b = B(); + } + + void a6(B b = B()); + + A(int a = 42); // expected-note{{default argument declared here}} + + // CHECK: error: use of undeclared identifier 'third' + void a7(int a = third); // expected-error{{use of undeclared identifier 'third'}} +}; diff --git a/clang/test/CXX/class/class.mem/p2.cpp b/clang/test/CXX/class/class.mem/p2.cpp new file mode 100644 index 0000000..4aa4a5c --- /dev/null +++ b/clang/test/CXX/class/class.mem/p2.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// C++11 [class.mem]p2: +// A class is considered a completely-defined object type (or +// complete type) at the closing } of the class-specifier. Within +// the class member-specification, the class is regarded as complete +// within function bodies, default arguments, +// exception-specifications, and brace-or-equal-initializers for +// non-static data members (including such things in nested classes). +// Otherwise it is regarded as incomplete within its own class +// member-specification. + +namespace test0 { + struct A { // expected-note {{definition of 'test0::A' is not complete until the closing '}'}} + A x; // expected-error {{field has incomplete type 'test0::A'}} + }; +} + +namespace test1 { + template struct A { + A x; // expected-error {{implicit instantiation of template 'test1::A' within its own definition}} + }; +} + +namespace test2 { + template struct A; + template <> struct A {}; + template struct A { + A x; + }; +} + +namespace test3 { + struct A { + struct B { + void f() throw(A); + void g() throw(B); + }; + + void f() throw(A); + void g() throw(B); + }; + + template + struct A2 { + struct B { + void f1() throw(A2); + void f2() throw(A2); + void g() throw(B); + }; + + void f1() throw(A2); + void f2() throw(A2); + void g() throw(B); + }; + + template struct A2; +} diff --git a/clang/test/CXX/class/class.mem/p5-0x.cpp b/clang/test/CXX/class/class.mem/p5-0x.cpp new file mode 100644 index 0000000..6061c4c --- /dev/null +++ b/clang/test/CXX/class/class.mem/p5-0x.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +int f(); + +struct S +{ + int a = f(); // ok + int b = g(); // expected-error {{use of undeclared identifier 'g'}} +}; diff --git a/clang/test/CXX/class/class.mem/p8-0x.cpp b/clang/test/CXX/class/class.mem/p8-0x.cpp new file mode 100644 index 0000000..d2c3dc3 --- /dev/null +++ b/clang/test/CXX/class/class.mem/p8-0x.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +struct Base1 { + virtual void g(); +}; + +struct A : Base1 { + virtual void g() override override; // expected-error {{class member already marked 'override'}} + virtual void h() final final; // expected-error {{class member already marked 'final'}} +}; + +struct Base2 { + virtual void e1(), e2(); + virtual void f(); +}; + +struct B : Base2 { + virtual void e1() override, e2(int); // No error. + virtual void f() override; + void g() override; // expected-error {{only virtual member functions can be marked 'override'}} + int h override; // expected-error {{only virtual member functions can be marked 'override'}} +}; + +struct C { + virtual void f() final; + void g() final; // expected-error {{only virtual member functions can be marked 'final'}} + int h final; // expected-error {{only virtual member functions can be marked 'final'}} +}; + +namespace inline_extension { + struct Base1 { + virtual void g() {} + }; + + struct A : Base1 { + virtual void g() override override {} // expected-error {{class member already marked 'override'}} + virtual void h() final final {} // expected-error {{class member already marked 'final'}} + }; + + struct Base2 { + virtual void f(); + }; + + struct B : Base2 { + virtual void f() override {} + void g() override {} // expected-error {{only virtual member functions can be marked 'override'}} + }; + + struct C { + virtual void f() final {} + void g() final {} // expected-error {{only virtual member functions can be marked 'final'}} + }; +} diff --git a/clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp new file mode 100644 index 0000000..9116e71 --- /dev/null +++ b/clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// [class.mfct.non-static]p3: +// When an id-expression (5.1) that is not part of a class member +// access syntax (5.2.5) and not used to form a pointer to member +// (5.3.1) is used in the body of a non-static member function of +// class X, if name lookup (3.4.1) resolves the name in the +// id-expression to a non-static non-type member of some class C, +// the id-expression is transformed into a class member access +// expression (5.2.5) using (*this) (9.3.2) as the +// postfix-expression to the left of the . operator. [ Note: if C is +// not X or a base class of X, the class member access expression is +// ill-formed. --end note] Similarly during name lookup, when an +// unqualified-id (5.1) used in the definition of a member function +// for class X resolves to a static member, an enumerator or a +// nested type of class X or of a base class of X, the +// unqualified-id is transformed into a qualified-id (5.1) in which +// the nested-name-specifier names the class of the member function. + +namespace test0 { + class A { + int data_member; + int instance_method(); + static int static_method(); + + bool test() { + return data_member + instance_method() < static_method(); + } + }; +} + +namespace test1 { + struct Opaque1 {}; struct Opaque2 {}; struct Opaque3 {}; + + struct A { + void foo(Opaque1); // expected-note {{candidate}} + void foo(Opaque2); // expected-note {{candidate}} + }; + + struct B : A { + void test(); + }; + + struct C1 : A { }; + struct C2 : B { }; + + void B::test() { + A::foo(Opaque1()); + A::foo(Opaque2()); + A::foo(Opaque3()); // expected-error {{no matching member function}} + + C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}} + C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}} + } +} + +namespace test2 { + struct Unrelated { + void foo(); + }; + + template struct B; + template struct C; + + template struct A { + void foo(); + + void test0() { + Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}} + } + + void test1() { + B::foo(); + } + + static void test2() { + B::foo(); // expected-error {{call to non-static member function without an object argument}} + } + + void test3() { + C::foo(); // expected-error {{no member named 'foo'}} + } + }; + + template struct B : A { + }; + + template struct C { + }; + + int test() { + A a; + a.test0(); // no instantiation note here, decl is ill-formed + a.test1(); + a.test2(); // expected-note {{in instantiation}} + a.test3(); // expected-note {{in instantiation}} + } +} diff --git a/clang/test/CXX/class/class.nest/p1-cxx0x.cpp b/clang/test/CXX/class/class.nest/p1-cxx0x.cpp new file mode 100644 index 0000000..b7a1a48 --- /dev/null +++ b/clang/test/CXX/class/class.nest/p1-cxx0x.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +class Outer { + int x; + static int sx; + int f(); + + // The first case is invalid in the C++03 mode but valid in C++0x (see 5.1.1.10). + class Inner { + static char a[sizeof(x)]; // okay + static char b[sizeof(sx)]; // okay + static char c[sizeof(f)]; // expected-error {{call to non-static member function without an object argument}} + }; +}; diff --git a/clang/test/CXX/class/class.nest/p1.cpp b/clang/test/CXX/class/class.nest/p1.cpp new file mode 100644 index 0000000..b0341da --- /dev/null +++ b/clang/test/CXX/class/class.nest/p1.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class Outer { + int x; + static int sx; + int f(); + + // C++11 does relax this rule (see 5.1.1.10) in the first case, but we need to enforce it in C++03 mode. + class Inner { + static char a[sizeof(x)]; // expected-error {{invalid use of non-static data member 'x'}} + static char b[sizeof(sx)]; // okay + static char c[sizeof(f)]; // expected-error {{call to non-static member function without an object argument}} + }; +}; diff --git a/clang/test/CXX/class/class.nest/p3.cpp b/clang/test/CXX/class/class.nest/p3.cpp new file mode 100644 index 0000000..c4c4ca7 --- /dev/null +++ b/clang/test/CXX/class/class.nest/p3.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [class.nest] p3: +// If class X is defined in a namespace scope, a nested class Y may be +// declared in class X and later defined in the definition of class X or be +// later defined in a namespace scope enclosing the definition of class X. + +namespace example { + class E { + class I1; + class I2; + class I1 { }; + }; + class E::I2 { }; +} + +// Don't insert out-of-line inner class definitions into the namespace scope. +namespace PR6107 { + struct S1 { }; + struct S2 { + struct S1; + }; + struct S2::S1 { }; + S1 s1; +} diff --git a/clang/test/CXX/class/class.nested.type/p1.cpp b/clang/test/CXX/class/class.nested.type/p1.cpp new file mode 100644 index 0000000..4a04a44 --- /dev/null +++ b/clang/test/CXX/class/class.nested.type/p1.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class X { +public: + typedef int I; + class Y { }; + I a; +}; + +I b; // expected-error{{unknown type name 'I'}} +Y c; // expected-error{{unknown type name 'Y'}} +X::Y d; +X::I e; diff --git a/clang/test/CXX/class/class.static/class.static.data/p3.cpp b/clang/test/CXX/class/class.static/class.static.data/p3.cpp new file mode 100644 index 0000000..117997e --- /dev/null +++ b/clang/test/CXX/class/class.static/class.static.data/p3.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct NonLit { // expected-note 3{{no constexpr constructors}} + NonLit(); +}; + +struct S { + static constexpr int a = 0; + static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}} + + static constexpr int c = 0; + static const int d; + static const int d2 = 0; + + static constexpr double e = 0.0; // ok + static const double f = 0.0; // expected-warning {{extension}} expected-note {{use 'constexpr' specifier}} + static char *const g = 0; // expected-error {{requires 'constexpr' specifier}} + static const NonLit h = NonLit(); // expected-error {{must be initialized out of line}} +}; + +constexpr int S::a; +constexpr int S::b = 0; + +const int S::c; +constexpr int S::d = 0; +constexpr int S::d2; + +template +struct U { + static constexpr int a = 0; + static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}} + static constexpr NonLit h = NonLit(); // expected-error {{cannot have non-literal type 'const NonLit'}} + static constexpr T c = T(); // expected-error {{cannot have non-literal type}} + static const T d; +}; + +template constexpr T U::d = T(); // expected-error {{non-literal type 'const NonLit'}} + +U u1; +U u2; // expected-note {{here}} + +static_assert(U::a == 0, ""); + +constexpr int outofline = (U::d, 0); // expected-note {{here}} expected-warning {{unused}} diff --git a/clang/test/CXX/class/class.static/class.static.data/p4.cpp b/clang/test/CXX/class/class.static/class.static.data/p4.cpp new file mode 100644 index 0000000..2b1eca7 --- /dev/null +++ b/clang/test/CXX/class/class.static/class.static.data/p4.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct InClassInitializerOnly { + static const int i = 0; +}; +int const InClassInitializerOnly::i; + +struct OutOfClassInitializerOnly { + static const int i; +}; +int const OutOfClassInitializerOnly::i = 0; + +struct InClassInitializerAndOutOfClassCopyInitializer { + static const int i = 0; // expected-note{{previous definition is here}} +}; +int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{redefinition of 'i'}} + +struct InClassInitializerAndOutOfClassDirectInitializer { + static const int i = 0; // expected-note{{previous definition is here}} +}; +int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{redefinition of 'i'}} + + + +int main() { } + diff --git a/clang/test/CXX/class/class.union/p1.cpp b/clang/test/CXX/class/class.union/p1.cpp new file mode 100644 index 0000000..f344ae5 --- /dev/null +++ b/clang/test/CXX/class/class.union/p1.cpp @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void abort() __attribute__((noreturn)); + +class Okay { + int a_; +}; + +class Virtual { + virtual void foo() { abort(); } // expected-note 4 {{because type 'Virtual' has a virtual member function}} +}; + +class VirtualBase : virtual Okay { // expected-note 4 {{because type 'VirtualBase' has a virtual base class}} +}; + +class Ctor { + Ctor() { abort(); } // expected-note 4 {{because type 'Ctor' has a user-declared constructor}} +}; +class Ctor2 { + Ctor2(); // expected-note 3 {{because type 'Ctor2' has a user-declared constructor}} +}; +class CtorTmpl { + template CtorTmpl(); // expected-note {{because type 'CtorTmpl' has a user-declared constructor}} +}; + +class CopyCtor { + CopyCtor(CopyCtor &cc) { abort(); } // expected-note 4 {{because type 'CopyCtor' has a user-declared copy constructor}} +}; + +// FIXME: this should eventually trigger on the operator's declaration line +class CopyAssign { // expected-note 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}} + CopyAssign& operator=(CopyAssign& CA) { abort(); } +}; + +class Dtor { + ~Dtor() { abort(); } // expected-note 4 {{because type 'Dtor' has a user-declared destructor}} +}; + +union U1 { + Virtual v; // expected-error {{union member 'v' has a non-trivial copy constructor}} + VirtualBase vbase; // expected-error {{union member 'vbase' has a non-trivial copy constructor}} + Ctor ctor; // expected-error {{union member 'ctor' has a non-trivial constructor}} + Ctor2 ctor2; // expected-error {{union member 'ctor2' has a non-trivial constructor}} + CtorTmpl ctortmpl; // expected-error {{union member 'ctortmpl' has a non-trivial constructor}} + CopyCtor copyctor; // expected-error {{union member 'copyctor' has a non-trivial copy constructor}} + CopyAssign copyassign; // expected-error {{union member 'copyassign' has a non-trivial copy assignment operator}} + Dtor dtor; // expected-error {{union member 'dtor' has a non-trivial destructor}} + Okay okay; +}; + +union U2 { + struct { + Virtual v; // expected-note {{because type 'U2:: struct Either { + bool tag; + union { // expected-note 6 {{in instantiation of member class}} + A a; + B b; // expected-error 6 {{non-trivial}} + }; + + Either(const A& a) : tag(true), a(a) {} + Either(const B& b) : tag(false), b(b) {} +}; + +void fred() { + Either virt(0); // expected-note {{in instantiation of template}} + Either vbase(0); // expected-note {{in instantiation of template}} + Either ctor(0); // expected-note {{in instantiation of template}} + Either copyctor(0); // expected-note {{in instantiation of template}} + Either copyassign(0); // expected-note {{in instantiation of template}} + Either dtor(0); // expected-note {{in instantiation of template}} + Either okay(0); +} diff --git a/clang/test/CXX/class/class.union/p2-0x.cpp b/clang/test/CXX/class/class.union/p2-0x.cpp new file mode 100644 index 0000000..b5c4109 --- /dev/null +++ b/clang/test/CXX/class/class.union/p2-0x.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +// Unlike in C++98, C++11 allows unions to have static data members. + +union U1 { + static constexpr int k1 = 0; + static const int k2 = k1; + static int k3 = k2; // expected-error {{non-const static data member must be initialized out of line}} + static constexpr double k4 = k2; + static const double k5 = k4; // expected-warning {{GNU extension}} expected-note {{use 'constexpr'}} + int n[k1 + 3]; +}; + +constexpr int U1::k1; +constexpr int U1::k2; +int U1::k3; + +const double U1::k4; +const double U1::k5; + +template +union U2 { + static const int k1; + static double k2; + T t; +}; +template constexpr int U2::k1 = sizeof(U2); +template double U2::k2 = 5.3; + +static_assert(U2::k1 == sizeof(int), ""); +static_assert(U2::k1 == sizeof(char), ""); + +union U3 { + static const int k; + U3() : k(0) {} // expected-error {{does not name a non-static data member}} +}; + +struct S { + union { + static const int n; // expected-error {{static members cannot be declared in an anonymous union}} + int a; + int b; + }; +}; +static union { + static const int k; // expected-error {{static members cannot be declared in an anonymous union}} + int n; +}; diff --git a/clang/test/CXX/class/p1-0x.cpp b/clang/test/CXX/class/p1-0x.cpp new file mode 100644 index 0000000..be5fdff --- /dev/null +++ b/clang/test/CXX/class/p1-0x.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +namespace Test1 { + +class A final { }; + +} diff --git a/clang/test/CXX/class/p2-0x.cpp b/clang/test/CXX/class/p2-0x.cpp new file mode 100644 index 0000000..dbb01e5 --- /dev/null +++ b/clang/test/CXX/class/p2-0x.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +namespace Test1 { + +class A final { }; // expected-note {{'A' declared here}} +class B : A { }; // expected-error {{base 'A' is marked 'final'}} + +} + +namespace Test2 { + +template struct A final { }; // expected-note 2 {{'A' declared here}} +struct B : A { }; // expected-error {{base 'A' is marked 'final'}} + +template struct C : A { }; // expected-error {{base 'A' is marked 'final'}} +struct D : C { }; // expected-note {{in instantiation of template class 'Test2::C' requested here}} + +} + +namespace Test3 { + +template struct A { }; +template<> struct A final { }; // expected-note {{'A' declared here}} + +struct B : A { }; +struct C : A { }; // expected-error {{base 'A' is marked 'final'}} + +} + diff --git a/clang/test/CXX/class/p6-0x.cpp b/clang/test/CXX/class/p6-0x.cpp new file mode 100644 index 0000000..f2cf482 --- /dev/null +++ b/clang/test/CXX/class/p6-0x.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +class Trivial { int n; void f(); }; +class NonTrivial1 { NonTrivial1(const NonTrivial1 &); }; +class NonTrivial2 { NonTrivial2(NonTrivial2 &&); }; +class NonTrivial3 { NonTrivial3 operator=(const NonTrivial3 &); }; +class NonTrivial4 { NonTrivial4 operator=(NonTrivial4 &&); }; +class NonTrivial5 { ~NonTrivial5(); }; + +static_assert(__is_trivial(Trivial), "Trivial is not trivial"); +static_assert(!__is_trivial(NonTrivial1), "NonTrivial1 is trivial"); +static_assert(!__is_trivial(NonTrivial2), "NonTrivial2 is trivial"); +static_assert(!__is_trivial(NonTrivial3), "NonTrivial3 is trivial"); +static_assert(!__is_trivial(NonTrivial4), "NonTrivial4 is trivial"); +static_assert(!__is_trivial(NonTrivial5), "NonTrivial5 is trivial"); + +struct Trivial2 { + Trivial2() = default; + Trivial2(const Trivial2 &) = default; + Trivial2(Trivial2 &&) = default; + Trivial2 &operator=(const Trivial2 &) = default; + Trivial2 &operator=(Trivial2 &) = default; + ~Trivial2() = default; +}; + +class NonTrivial6 { ~NonTrivial6(); }; + +NonTrivial6::~NonTrivial6() = default; + +static_assert(!__is_trivial(NonTrivial6), "NonTrivial6 is trivial"); diff --git a/clang/test/CXX/conv/conv.mem/p4.cpp b/clang/test/CXX/conv/conv.mem/p4.cpp new file mode 100644 index 0000000..e0748d8 --- /dev/null +++ b/clang/test/CXX/conv/conv.mem/p4.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct Base { + int data; + int method(); +}; +int (Base::*data_ptr) = &Base::data; +int (Base::*method_ptr)() = &Base::method; + +namespace test0 { + struct Derived : Base {}; + void test() { + int (Derived::*d) = data_ptr; + int (Derived::*m)() = method_ptr; + } +} + +// Can't be inaccessible. +namespace test1 { + struct Derived : private Base {}; // expected-note 2 {{declared private here}} + void test() { + int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}} + int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}} + } +}; + +// Can't be ambiguous. +namespace test2 { + struct A : Base {}; + struct B : Base {}; + struct Derived : A, B {}; + void test() { + int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}} + int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}} + } +} + +// Can't be virtual. +namespace test3 { + struct Derived : virtual Base {}; + void test() { + int (Derived::*d) = data_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}} + int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}} + } +} + +// Can't be virtual even if there's a non-virtual path. +namespace test4 { + struct A : Base {}; + struct Derived : Base, virtual A {}; + void test() { + int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}} + int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}} + } +} + +// PR6254: don't get thrown off by a virtual base. +namespace test5 { + struct A {}; + struct Derived : Base, virtual A {}; + void test() { + int (Derived::*d) = data_ptr; + int (Derived::*m)() = method_ptr; + } +} diff --git a/clang/test/CXX/conv/conv.prom/p2.cpp b/clang/test/CXX/conv/conv.prom/p2.cpp new file mode 100644 index 0000000..8d75419 --- /dev/null +++ b/clang/test/CXX/conv/conv.prom/p2.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -ffreestanding %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fshort-wchar -ffreestanding %s + +#include + +// In theory, the promoted types vary by platform; however, in reality they +// are quite consistent across all platforms where clang runs. + +extern int promoted_wchar; +extern decltype(+L'a') promoted_wchar; + +extern int promoted_char16; +extern decltype(+u'a') promoted_char16; + +extern unsigned promoted_char32; +extern decltype(+U'a') promoted_char32; diff --git a/clang/test/CXX/conv/conv.prom/p4.cpp b/clang/test/CXX/conv/conv.prom/p4.cpp new file mode 100644 index 0000000..02a91cd --- /dev/null +++ b/clang/test/CXX/conv/conv.prom/p4.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +enum X : short { A, B }; +extern decltype(+A) x; +extern int x; + +enum Y : long { C, D }; +extern decltype(+C) y; +extern long y; diff --git a/clang/test/CXX/conv/conv.ptr/p2.cpp b/clang/test/CXX/conv/conv.ptr/p2.cpp new file mode 100644 index 0000000..8808d20 --- /dev/null +++ b/clang/test/CXX/conv/conv.ptr/p2.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace pr7801 { + extern void* x[]; + void* dummy[] = { &x }; +} diff --git a/clang/test/CXX/conv/conv.qual/pr6089.cpp b/clang/test/CXX/conv/conv.qual/pr6089.cpp new file mode 100644 index 0000000..ae75ec4 --- /dev/null +++ b/clang/test/CXX/conv/conv.qual/pr6089.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +bool is_char_ptr( const char* ); + +template< class T > + long is_char_ptr( T /* r */ ); + +// Note: the const here does not lead to a qualification conversion +template< class T > + void make_range( T* const r, bool ); + +template< class T > + void make_range( T& r, long ); + +void first_finder( const char*& Search ) +{ + make_range( Search, is_char_ptr(Search) ); +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp new file mode 100644 index 0000000..069ca0a --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify + +// C++'0x [namespace.memdef] p3: +// Every name first declared in a namespace is a member of that namespace. If +// a friend declaration in a non-local class first declares a class or +// function the friend class or function is a member of the innermost +// enclosing namespace. + +namespace N { + struct S0 { + friend struct F0; + friend void f0(int); + struct F0 member_func(); + }; + struct F0 { }; + F0 f0() { return S0().member_func(); } +} +N::F0 f0_var = N::f0(); + +// Ensure we can handle attaching friend declarations to an enclosing namespace +// with multiple contexts. +namespace N { struct S1 { struct IS1; }; } +namespace N { + struct S1::IS1 { + friend struct F1; + friend void f1(int); + struct F1 member_func(); + }; + struct F1 { }; + F1 f1() { return S1::IS1().member_func(); } +} +N::F1 f1_var = N::f1(); + +// The name of the friend is not found by unqualified lookup (3.4.1) or by +// qualified lookup (3.4.3) until a matching declaration is provided in that +// namespace scope (either before or after the class definition granting +// friendship). If a friend function is called, its name may be found by the +// name lookup that considers functions from namespaces and classes +// associated with the types of the function arguments (3.4.2). If the name +// in a friend declaration is neither qualified nor a template-id and the +// declaration is a function or an elaborated-type-specifier, the lookup to +// determine whether the entity has been previously declared shall not +// consider any scopes outside the innermost enclosing namespace. + +template struct X0 { }; +struct X1 { }; + +struct Y { + template union X0; + template friend union X0; + + union X1; + friend union X1; +}; + +namespace N { + namespace M { + template class X; + } +} + +namespace N3 { + class Y { + template friend class N::M::X; + }; +} + +// FIXME: Woefully inadequate for testing + +// Friends declared as template-ids aren't subject to the restriction +// on innermost namespaces. +// rdar://problem/8552377 +namespace test5 { + template void f(T); + namespace ns { + class A { + friend void f(int); + static void foo(); // expected-note 2 {{declared private here}} + }; + + // Note that this happens without instantiation. + template void f(T) { + A::foo(); // expected-error {{'foo' is a private member of 'test5::ns::A'}} + } + } + + template void f(T) { + ns::A::foo(); // expected-error {{'foo' is a private member of 'test5::ns::A'}} + } + + template void f(int); + template void f(long); //expected-note {{instantiation}} +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp new file mode 100644 index 0000000..b4ec585 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -emit-llvm-only -verify %s + +// This lame little test was ripped straight from the standard. +namespace { + int i; // expected-note {{candidate}} +} +void test0() { i++; } + +namespace A { + namespace { + int i; // expected-note {{candidate}} + int j; + } + void test1() { i++; } +} + +using namespace A; + +void test2() { + i++; // expected-error {{reference to 'i' is ambiguous}} + A::i++; + j++; +} + + +// Test that all anonymous namespaces in a translation unit are +// considered the same context. +namespace { + class Test3 {}; // expected-note {{previous definition}} +} +namespace { + class Test3 {}; // expected-error {{redefinition of 'Test3'}} +} + +namespace test4 { + namespace { + class Test4 {}; // expected-note {{previous definition}} + } + namespace { + class Test4 {}; // expected-error {{redefinition of 'Test4'}} + } +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp new file mode 100644 index 0000000..6ffa873 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s + +// Intentionally compiled as C++03 to test the extension warning. + +namespace a {} // original +namespace a {} // ext +inline namespace b {} // inline original expected-warning {{inline namespaces are}} +inline namespace b {} // inline ext expected-warning {{inline namespaces are}} +inline namespace {} // inline unnamed expected-warning {{inline namespaces are}} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp new file mode 100644 index 0000000..411c16c --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR8430 +namespace N { + class A { }; +} + +namespace M { } + +using namespace M; + +namespace N { + namespace M { + } +} + +namespace M { + namespace N { + } +} + +namespace N { + A *getA(); +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp new file mode 100644 index 0000000..98d12f9 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +namespace NIL {} // expected-note {{previous definition}} +inline namespace NIL {} // expected-error {{cannot be reopened as inline}} +inline namespace IL {} // expected-note {{previous definition}} +namespace IL {} // expected-warning{{inline namespace cannot be re-opened as a non-inline namespace}} + +namespace {} // expected-note {{previous definition}} +inline namespace {} // expected-error {{cannot be reopened as inline}} +namespace X { + inline namespace {} // expected-note {{previous definition}} + namespace {} // expected-error {{cannot be reopened as non-inline}} +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp new file mode 100644 index 0000000..3bc4856 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// Fun things you can do with inline namespaces: + +inline namespace X { + void f1(); + + inline namespace Y { + void f2(); + + template class C {}; + } + + // Specialize and partially specialize somewhere else. + template <> class C {}; + template class C {}; +} + +// Qualified and unqualified lookup as if member of enclosing NS. +void foo1() { + f1(); + ::f1(); + X::f1(); + Y::f1(); // expected-error {{no member named 'f1' in namespace 'X::Y'}} + + f2(); + ::f2(); + X::f2(); + Y::f2(); +} + +template <> class C {}; +template class C {}; + +template class C; + + +// As well as all the fun with ADL. + +namespace ADL { + struct Outer {}; + + inline namespace IL { + struct Inner {}; + + void fo(Outer); + } + + void fi(Inner); + + inline namespace IL2 { + void fi2(Inner); + } +} + +void foo2() { + ADL::Outer o; + ADL::Inner i; + fo(o); + fi(i); + fi2(i); +} + +// Let's not forget overload sets. +struct Distinct {}; +inline namespace Over { + void over(Distinct); +} +void over(int); + +void foo3() { + Distinct d; + ::over(d); +} + +// Don't forget to do correct lookup for redeclarations. +namespace redecl { inline namespace n1 { + + template class allocator; + + template <> + class allocator + { + public: + typedef const void* const_pointer; + }; + + template + class allocator + { + public: + typedef Tp& reference; + + void allocate(allocator::const_pointer = 0); + }; + +} } + +// Normal redeclarations (not for explicit instantiations or +// specializations) are distinct in an inline namespace vs. not in an +// inline namespace. +namespace redecl2 { + inline namespace n1 { + void f(int) { } + struct X1 { }; + template void f(T) { } + template struct X2 { }; + int i = 71; + enum E { e }; + } + + void f(int) { } + struct X1 { }; + template void f(T) { } + template struct X2 { }; + int i = 71; + enum E { e }; +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp new file mode 100644 index 0000000..bf30ee7 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// We have to avoid ADL for this test. + +template class test {}; + +class foo {}; // expected-note {{candidate}} +test<0> foo(foo); // expected-note {{candidate}} + +namespace Test0 { + class foo { int x; }; + test<1> foo(class foo); + + namespace A { + test<2> foo(class ::foo); // expected-note {{candidate}} \ + // expected-note{{passing argument to parameter here}} + + void test0() { + using ::foo; + + class foo a; + test<0> _ = (foo)(a); + } + + void test1() { + using Test0::foo; + + class foo a; + test<1> _ = (foo)(a); + }; + + void test2() { + class ::foo a; + + // Argument-dependent lookup is ambiguous between B:: and ::. + test<0> _0 = foo(a); // expected-error {{call to 'foo' is ambiguous}} + + // But basic unqualified lookup is not. + test<2> _1 = (foo)(a); + + class Test0::foo b; + test<2> _2 = (foo)(b); // expected-error {{no viable conversion from 'class Test0::foo' to 'class ::foo'}} + } + } +} + +namespace Test1 { + namespace A { + class a {}; + } + + namespace B { + typedef class {} b; + } + + namespace C { + int c(); // expected-note {{target of using declaration}} + } + + namespace D { + using typename A::a; + using typename B::b; + using typename C::c; // expected-error {{'typename' keyword used on a non-type}} + + a _1 = A::a(); + b _2 = B::b(); + } +} + +namespace test2 { + class A { + protected: + operator int(); + operator bool(); + }; + + class B : private A { + protected: + using A::operator int; // expected-note {{declared protected here}} + public: + using A::operator bool; + }; + + int test() { + bool b = B(); + return B(); // expected-error {{'operator int' is a protected member of 'test2::B'}} + } +} + +namespace test3 { + class A { + public: + ~A(); + }; + + class B { + friend class C; + private: + operator A*(); + }; + + class C : public B { + public: + using B::operator A*; + }; + + void test() { + delete C(); + } +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp new file mode 100644 index 0000000..546c4a4 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test0 { + namespace ns0 { + class tag; + int tag(); + } + + namespace ns1 { + using ns0::tag; + } + + namespace ns2 { + using ns0::tag; + } + + using ns1::tag; + using ns2::tag; +} + +// PR 5752 +namespace test1 { + namespace ns { + void foo(); + } + + using ns::foo; + void foo(int); + + namespace ns { + using test1::foo; + } +} + diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp new file mode 100644 index 0000000..c7966ce --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++03 [namespace.udecl]p11: +// If a function declaration in namespace scope or block scope has +// the same name and the same parameter types as a function +// introduced by a using-declaration, the program is +// ill-formed. [Note: two using-declarations may introduce functions +// with the same name and the same parameter types. If, for a call +// to an unqualified function name, function overload resolution +// selects the functions introduced by such using-declarations, the +// function call is ill-formed. + +namespace test0 { + namespace ns { void foo(); } // expected-note {{target of using declaration}} + int foo(void); // expected-note {{conflicting declaration}} + using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}} +} + +namespace test1 { + namespace ns { void foo(); } // expected-note {{target of using declaration}} + using ns::foo; //expected-note {{using declaration}} + int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}} +} + +namespace test2 { + namespace ns { void foo(); } // expected-note 2 {{target of using declaration}} + void test0() { + int foo(void); // expected-note {{conflicting declaration}} + using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}} + } + + void test1() { + using ns::foo; //expected-note {{using declaration}} + int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}} + } +} + +namespace test3 { + namespace ns { void foo(); } // expected-note 2 {{target of using declaration}} + class Test0 { + void test() { + int foo(void); // expected-note {{conflicting declaration}} + using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}} + } + }; + + class Test1 { + void test() { + using ns::foo; //expected-note {{using declaration}} + int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}} + } + }; +} + +namespace test4 { + namespace ns { void foo(); } // expected-note 2 {{target of using declaration}} + template class Test0 { + void test() { + int foo(void); // expected-note {{conflicting declaration}} + using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}} + } + }; + + template class Test1 { + void test() { + using ns::foo; //expected-note {{using declaration}} + int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}} + } + }; +} + +// FIXME: we should be able to diagnose both of these, but we can't. +namespace test5 { + namespace ns { void foo(int); } + template class Test0 { + void test() { + int foo(T); + using ns::foo; + } + }; + + template class Test1 { + void test() { + using ns::foo; + int foo(T); + } + }; + + template class Test0; + template class Test1; +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp new file mode 100644 index 0000000..cc28bf6 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp @@ -0,0 +1,163 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++03 [namespace.udecl]p12: +// When a using-declaration brings names from a base class into a +// derived class scope, member functions in the derived class +// override and/or hide member functions with the same name and +// parameter types in a base class (rather than conflicting). + +template struct Opaque {}; +template void expect(Opaque _) {} + +// PR5727 +// This just shouldn't crash. +namespace test0 { + template struct RefPtr { }; + template struct PtrHash { + static void f() { } + }; + template struct PtrHash > : PtrHash { + using PtrHash::f; + static void f() { f(); } + }; +} + +// Simple hiding. +namespace test1 { + struct Base { + Opaque<0> foo(Opaque<0>); + Opaque<0> foo(Opaque<1>); + Opaque<0> foo(Opaque<2>); + }; + + // using before decls + struct Test0 : Base { + using Base::foo; + Opaque<1> foo(Opaque<1>); + Opaque<1> foo(Opaque<3>); + + void test0() { Opaque<0> _ = foo(Opaque<0>()); } + void test1() { Opaque<1> _ = foo(Opaque<1>()); } + void test2() { Opaque<0> _ = foo(Opaque<2>()); } + void test3() { Opaque<1> _ = foo(Opaque<3>()); } + }; + + // using after decls + struct Test1 : Base { + Opaque<1> foo(Opaque<1>); + Opaque<1> foo(Opaque<3>); + using Base::foo; + + void test0() { Opaque<0> _ = foo(Opaque<0>()); } + void test1() { Opaque<1> _ = foo(Opaque<1>()); } + void test2() { Opaque<0> _ = foo(Opaque<2>()); } + void test3() { Opaque<1> _ = foo(Opaque<3>()); } + }; + + // using between decls + struct Test2 : Base { + Opaque<1> foo(Opaque<0>); + using Base::foo; + Opaque<1> foo(Opaque<2>); + Opaque<1> foo(Opaque<3>); + + void test0() { Opaque<1> _ = foo(Opaque<0>()); } + void test1() { Opaque<0> _ = foo(Opaque<1>()); } + void test2() { Opaque<1> _ = foo(Opaque<2>()); } + void test3() { Opaque<1> _ = foo(Opaque<3>()); } + }; +} + +// Crazy dependent hiding. +namespace test2 { + struct Base { + void foo(int); + }; + + template struct Derived1 : Base { + using Base::foo; + void foo(T); + + void testUnresolved(int i) { foo(i); } + }; + + void test0(int i) { + Derived1 d1; + d1.foo(i); + d1.testUnresolved(i); + } + + // Same thing, except with the order of members reversed. + template struct Derived2 : Base { + void foo(T); + using Base::foo; + + void testUnresolved(int i) { foo(i); } + }; + + void test1(int i) { + Derived2 d2; + d2.foo(i); + d2.testUnresolved(i); + } +} + +// Hiding of member templates. +namespace test3 { + struct Base { + template Opaque<0> foo() { return Opaque<0>(); } + template Opaque<1> foo() { return Opaque<1>(); } + }; + + struct Derived1 : Base { + using Base::foo; + template Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} + }; + + struct Derived2 : Base { + template Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} + using Base::foo; + }; + + struct Derived3 : Base { + using Base::foo; + template Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} + }; + + struct Derived4 : Base { + template Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} + using Base::foo; + }; + + void test() { + expect<0>(Base().foo()); + expect<1>(Base().foo<0>()); + expect<0>(Derived1().foo()); // expected-error {{no matching member function for call to 'foo'}} + expect<2>(Derived1().foo<0>()); + expect<0>(Derived2().foo()); // expected-error {{no matching member function for call to 'foo'}} + expect<2>(Derived2().foo<0>()); + expect<3>(Derived3().foo()); + expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + expect<3>(Derived4().foo()); + expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + } +} + +// PR7384: access control for member templates. +namespace test4 { + class Base { + protected: + template void foo(T); + template void bar(T); // expected-note {{declared protected here}} + }; + + struct Derived : Base { + using Base::foo; + }; + + void test() { + Derived d; + d.foo(3); + d.bar(3); // expected-error {{'bar' is a protected member}} + } +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp new file mode 100644 index 0000000..dd44bfc --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++03 [namespace.udecl]p3: +// For the purpose of overload resolution, the functions which are +// introduced by a using-declaration into a derived class will be +// treated as though they were members of the derived class. In +// particular, the implicit this parameter shall be treated as if it +// were a pointer to the derived class rather than to the base +// class. This has no effect on the type of the function, and in all +// other respects the function remains a member of the base class. + +namespace test0 { + struct Opaque0 {}; + struct Opaque1 {}; + + struct Base { + Opaque0 test0(int*); + Opaque0 test1(const int*); + Opaque0 test2(int*); + Opaque0 test3(int*) const; + }; + + struct Derived : Base { + using Base::test0; + Opaque1 test0(const int*); + + using Base::test1; + Opaque1 test1(int*); + + using Base::test2; + Opaque1 test2(int*) const; + + using Base::test3; + Opaque1 test3(int*); + }; + + void test0() { + Opaque0 a = Derived().test0((int*) 0); + Opaque1 b = Derived().test0((const int*) 0); + } + + void test1() { + Opaque1 a = Derived().test1((int*) 0); + Opaque0 b = Derived().test1((const int*) 0); + } + + void test2() { + Opaque0 a = ((Derived*) 0)->test2((int*) 0); + Opaque1 b = ((const Derived*) 0)->test2((int*) 0); + } + + void test3() { + Opaque1 a = ((Derived*) 0)->test3((int*) 0); + Opaque0 b = ((const Derived*) 0)->test3((int*) 0); + } +} + +// Typedef redeclaration. +namespace rdar8018262 { + typedef void (*fp)(); + + namespace N { + typedef void (*fp)(); + } + + using N::fp; + + fp fp_1; +} + +// Things to test: +// member operators +// conversion operators +// call operators +// call-surrogate conversion operators +// everything, but in dependent contexts diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp new file mode 100644 index 0000000..f61437e --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// C++0x N2914. + +struct B { + void f(char); + void g(char); + enum E { e }; + union { int x; }; +}; + +class C { + int g(); +}; + +class D2 : public B { + using B::f; + using B::e; + using B::x; + using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}} +}; + +namespace test1 { + struct Base { + int foo(); + }; + + struct Unrelated { + int foo(); + }; + + struct Subclass : Base { + }; + + namespace InnerNS { + int foo(); + } + + // We should be able to diagnose these without instantiation. + template struct C : Base { + using InnerNS::foo; // expected-error {{not a class}} + using Base::bar; // expected-error {{no member named 'bar'}} + using Unrelated::foo; // expected-error {{not a base class}} + using C::foo; // expected-error {{refers to its own class}} + using Subclass::foo; // expected-error {{not a base class}} + }; +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp new file mode 100644 index 0000000..a43d9e0 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp @@ -0,0 +1,213 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++03 [namespace.udecl]p4: +// A using-declaration used as a member-declaration shall refer to a +// member of a base class of the class being defined, shall refer to +// a member of an anonymous union that is a member of a base class +// of the class being defined, or shall refer to an enumerator for +// an enumeration type that is a member of a base class of the class +// being defined. + +// There is no directly analogous paragraph in C++0x, and the feature +// works sufficiently differently there that it needs a separate test. + +namespace test0 { + namespace NonClass { + typedef int type; + struct hiding {}; + int hiding; + static union { double union_member; }; + enum tagname { enumerator }; + } + + class Test0 { + using NonClass::type; // expected-error {{not a class}} + using NonClass::hiding; // expected-error {{not a class}} + using NonClass::union_member; // expected-error {{not a class}} + using NonClass::enumerator; // expected-error {{not a class}} + }; +} + +struct Opaque0 {}; + +namespace test1 { + struct A { + typedef int type; + struct hiding {}; // expected-note {{previous use is here}} + Opaque0 hiding; + union { double union_member; }; + enum tagname { enumerator }; + }; + + struct B : A { + using A::type; + using A::hiding; + using A::union_member; + using A::enumerator; + using A::tagname; + + void test0() { + type t = 0; + } + + void test1() { + typedef struct A::hiding local; + struct hiding _ = local(); + } + + void test2() { + union hiding _; // expected-error {{tag type that does not match previous}} + } + + void test3() { + char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; + } + + void test4() { + enum tagname _ = enumerator; + } + + void test5() { + Opaque0 _ = hiding; + } + }; +} + +namespace test2 { + struct A { + typedef int type; + struct hiding {}; // expected-note {{previous use is here}} + int hiding; + union { double union_member; }; + enum tagname { enumerator }; + }; + + template struct B : A { + using A::type; + using A::hiding; + using A::union_member; + using A::enumerator; + using A::tagname; + + void test0() { + type t = 0; + } + + void test1() { + typedef struct A::hiding local; + struct hiding _ = local(); + } + + void test2() { + union hiding _; // expected-error {{tag type that does not match previous}} + } + + void test3() { + char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; + } + + void test4() { + enum tagname _ = enumerator; + } + + void test5() { + Opaque0 _ = hiding; + } + }; +} + +namespace test3 { + struct hiding {}; + + template struct A { + typedef int type; // expected-note {{target of using declaration}} + struct hiding {}; + Opaque0 hiding; // expected-note {{target of using declaration}} + union { double union_member; }; // expected-note {{target of using declaration}} + enum tagname { enumerator }; // expected-note 2 {{target of using declaration}} + }; + + template struct B : A { + using A::type; // expected-error {{dependent using declaration resolved to type without 'typename'}} + using A::hiding; + using A::union_member; + using A::enumerator; + using A::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}} + + // FIXME: re-enable these when the various bugs involving tags are fixed +#if 0 + void test1() { + typedef struct A::hiding local; + struct hiding _ = local(); + } + + void test2() { + typedef struct A::hiding local; + union hiding _ = local(); + } +#endif + + void test3() { + char array[sizeof(union_member) == sizeof(double) ? 1 : -1]; + } + +#if 0 + void test4() { + enum tagname _ = enumerator; + } +#endif + + void test5() { + Opaque0 _ = hiding; + } + }; + + template struct B; // expected-note {{in instantiation}} + + template struct C : A { + using typename A::type; + using typename A::hiding; // expected-note {{declared here}} \ + // expected-error {{'typename' keyword used on a non-type}} + using typename A::union_member; // expected-error {{'typename' keyword used on a non-type}} + using typename A::enumerator; // expected-error {{'typename' keyword used on a non-type}} + + void test6() { + type t = 0; + } + + void test7() { + Opaque0 _ = hiding; // expected-error {{does not refer to a value}} + } + }; + + template struct C; // expected-note {{in instantiation}} +} + +namespace test4 { + struct Base { + int foo(); + }; + + struct Unrelated { + int foo(); + }; + + struct Subclass : Base { + }; + + namespace InnerNS { + int foo(); + } + + // We should be able to diagnose these without instantiation. + template struct C : Base { + using InnerNS::foo; // expected-error {{not a class}} + using Base::bar; // expected-error {{no member named 'bar'}} + using Unrelated::foo; // expected-error {{not a base class}} + using C::foo; // legal in C++03 + using Subclass::foo; // legal in C++03 + + int bar(); //expected-note {{target of using declaration}} + using C::bar; // expected-error {{refers to its own class}} + }; +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp new file mode 100644 index 0000000..edaa975 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// C++0x N2914. + +struct A { + template void f(T); + template struct X { }; +}; + +struct B : A { + using A::f; // expected-error{{using declaration can not refer to a template specialization}} + using A::X; // expected-error{{using declaration can not refer to a template specialization}} +}; diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp new file mode 100644 index 0000000..c4b8849 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// C++0x N2914. + +namespace A { + namespace B { } +} + +using A::B; // expected-error{{using declaration can not refer to namespace}} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp new file mode 100644 index 0000000..78b5a41 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// C++0x N2914. + +struct X { + int i; + static int a; +}; + +using X::i; // expected-error{{using declaration can not refer to class member}} +using X::s; // expected-error{{using declaration can not refer to class member}} + +void f() { + using X::i; // expected-error{{using declaration can not refer to class member}} + using X::s; // expected-error{{using declaration can not refer to class member}} +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp new file mode 100644 index 0000000..4660971 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct Opaque0 {}; +struct Opaque1 {}; + +// Redeclarations are okay in a namespace. +namespace test0 { + namespace ns { + void foo(Opaque0); // expected-note 2 {{candidate function}} + } + + using ns::foo; + using ns::foo; + + void test0() { + foo(Opaque1()); // expected-error {{no matching function for call}} + } + + namespace ns { + void foo(Opaque1); + } + + void test1() { + foo(Opaque1()); // expected-error {{no matching function for call}} + } + + using ns::foo; + + void test2() { + foo(Opaque1()); + } + + using ns::foo; +} + +// Make sure we handle transparent contexts the same way. +namespace test1 { + namespace ns { + void foo(Opaque0); // expected-note 2 {{candidate function}} + } + + extern "C++" { + using ns::foo; + } + + void test0() { + foo(Opaque1()); // expected-error {{no matching function for call}} + } + + namespace ns { + void foo(Opaque1); + } + + void test1() { + foo(Opaque1()); // expected-error {{no matching function for call}} + } + + extern "C++" { + using ns::foo; + } + + void test2() { + foo(Opaque1()); + } +} + +// Make sure we detect invalid redeclarations that can't be detected +// until template instantiation. +namespace test2 { + template struct Base { + typedef Base type; + void foo(); + }; + + template struct Derived : Base { + // These are invalid redeclarations, detectable only after + // instantiation. + using Base::foo; // expected-note {{previous using decl}} + using Base::type::foo; //expected-error {{redeclaration of using decl}} + }; + + template struct Derived; // expected-note {{in instantiation of template class}} +} + +// Redeclarations are okay in a function. +namespace test3 { + namespace N { + int f(int); + typedef int type; + } + + void g() { + using N::f; + using N::f; + using N::type; + using N::type; + } +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp new file mode 100644 index 0000000..20a19ab --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp @@ -0,0 +1,141 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// (this actually occurs before paragraph 1) +namespace test0 { + namespace A {} + class B { + using namespace A; // expected-error {{'using namespace' is not allowed in classes}} + }; +} + + +struct opaque0 {}; +struct opaque1 {}; + +// Test that names appear as if in deepest common ancestor. +namespace test1 { + namespace A { + namespace B { + opaque0 foo(); // expected-note {{candidate}} + } + } + + namespace C { + opaque1 foo(); // expected-note {{candidate}} + + opaque1 test() { + using namespace A::B; + return foo(); // C::foo + } + } + + opaque1 test() { + using namespace A::B; + using namespace C; + return foo(); // expected-error {{call to 'foo' is ambiguous}} + } +} + +// Same thing, but with the directives in namespaces. +namespace test2 { + namespace A { + namespace B { + opaque0 foo(); // expected-note {{candidate}} + } + } + + namespace C { + opaque1 foo(); // expected-note {{candidate}} + + namespace test { + using namespace A::B; + + opaque1 test() { + return foo(); // C::foo + } + } + } + + namespace test { + using namespace A::B; + using namespace C; + + opaque1 test() { + return foo(); // expected-error {{call to 'foo' is ambiguous}} + } + } +} + +// Transitivity. +namespace test3 { + namespace A { + namespace B { + opaque0 foo(); + } + } + namespace C { + using namespace A; + } + + opaque0 test0() { + using namespace C; + using namespace B; + return foo(); + } + + namespace D { + using namespace C; + } + namespace A { + opaque1 foo(); + } + + opaque1 test1() { + using namespace D; + return foo(); + } +} + +// Transitivity acts like synthetic using directives. +namespace test4 { + namespace A { + namespace B { + opaque0 foo(); // expected-note {{candidate}} + } + } + + namespace C { + using namespace A::B; + } + + opaque1 foo(); // expected-note {{candidate}} + + namespace A { + namespace D { + using namespace C; + } + + opaque0 test() { + using namespace D; + return foo(); + } + } + + opaque0 test() { + using namespace A::D; + return foo(); // expected-error {{call to 'foo' is ambiguous}} + } +} + +// Bug: using directives should be followed when parsing default +// arguments in scoped declarations. +class test5 { + int inc(int x); +}; +namespace Test5 { + int default_x = 0; +} +using namespace Test5; +int test5::inc(int x = default_x) { + return x+1; +} diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp new file mode 100644 index 0000000..4cb91cd --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// +typedef int pid_t; +namespace ns { + typedef int pid_t; +} +using namespace ns; +pid_t x; + +struct A { }; +namespace ns { + typedef ::A A; +} +A a; diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp new file mode 100644 index 0000000..f9702ba --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +namespace std_example { + +int p[10]; +void f() { + int x = 42, y[5]; + // FIXME: Produce a better diagnostic for this case. + int(p[[x] { return x; }()]); // expected-error {{expected ']'}} + y[[] { return 2; }()] = 2; // expected-error {{consecutive left square brackets}} +} + +} diff --git a/clang/test/CXX/dcl.dcl/dcl.enum/p5.cpp b/clang/test/CXX/dcl.dcl/dcl.enum/p5.cpp new file mode 100644 index 0000000..f260624 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.enum/p5.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s +template int force_same(T, T); + +// C++ [dcl.enum]p5: +// [...] If the underlying type is not fixed, the type of each enumerator is +// the type of its initializing value: +// - If an initializer is specified for an enumerator, the initializing +// value has the same type as the expression. +enum Bullet1 { + Bullet1Val1 = 'a', + Bullet1Val2 = 10u, + Bullet1Val1IsChar = sizeof(force_same(Bullet1Val1, char(0))), + Bullet1Val2IsUnsigned = sizeof(force_same(Bullet1Val2, unsigned(0))) +}; + +// - If no initializer is specified for the first enumerator, the +// initializing value has an unspecified integral type. +enum Bullet2 { + Bullet2Val, + Bullet2ValIsInt = sizeof(force_same(Bullet2Val, int(0))) +}; + +// - Otherwise the type of the initializing value is the same as the type +// of the initializing value of the preceding enumerator unless the +// incremented value is not representable in that type, in which case the +// type is an unspecified integral type sufficient to contain the +// incremented value. If no such type exists, the program is ill-formed. +enum Bullet3a { + Bullet3aVal1 = 17, + Bullet3aVal2, + Bullet3aVal2IsInt = sizeof(force_same(Bullet3aVal2, int(0))), + Bullet3aVal3 = 2147483647, + Bullet3aVal3IsInt = sizeof(force_same(Bullet3aVal3, int(0))), + Bullet3aVal4, + Bullet3aVal4IsUnsigned = sizeof(force_same(Bullet3aVal4, 0ul)) +}; + +enum Bullet3b { + Bullet3bVal1 = 17u, + Bullet3bVal2, + Bullet3bVal2IsInt = sizeof(force_same(Bullet3bVal2, 0u)), + Bullet3bVal3 = 2147483647u, + Bullet3bVal3IsInt = sizeof(force_same(Bullet3bVal3, 0u)), + Bullet3bVal4, + Bullet3bVal4IsUnsigned = sizeof(force_same(Bullet3bVal4, 0ul)) +}; + +enum Bullet3c { + Bullet3cVal1 = 0xFFFFFFFFFFFFFFFEull, + Bullet3cVal2, + Bullet3cVal3 // expected-warning{{not representable}} +}; + +// Following the closing brace of an enum-specifier, each enumerator has the +// type of its enumeration. +int array0[sizeof(force_same(Bullet3bVal3, Bullet3b(0)))? 1 : -1]; diff --git a/clang/test/CXX/dcl.dcl/dcl.link/p7.cpp b/clang/test/CXX/dcl.dcl/dcl.link/p7.cpp new file mode 100644 index 0000000..bd9ff3c --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.link/p7.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct X { }; + +// CHECK: @x1 = global %struct.X zeroinitializer +// CHECK: @x4 = global %struct.X zeroinitializer +// CHECK: @x2 = external global %struct.X +// CHECK: @x3 = external global %struct.X +extern "C" { + + + X x1; +} + +extern "C" X x2; + +extern X x3; + +X x4; + +X& get(int i) { + if (i == 1) + return x1; + else if (i == 2) + return x2; + else if (i == 3) + return x3; + else + return x4; +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp new file mode 100644 index 0000000..6820fc6 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -0,0 +1,123 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct notlit { // expected-note {{not literal because}} + notlit() {} +}; +struct notlit2 { + notlit2() {} +}; + +// valid declarations +constexpr int i1 = 0; +constexpr int f1() { return 0; } +struct s1 { + constexpr static int mi1 = 0; + const static int mi2; +}; +constexpr int s1::mi2 = 0; + +// invalid declarations +// not a definition of an object +constexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}} +// not a literal type +constexpr notlit nl1; // expected-error {{constexpr variable cannot have non-literal type 'const notlit'}} +// function parameters +void f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}} +// non-static member +struct s2 { + constexpr int mi1; // expected-error {{non-static data member cannot be constexpr}} + static constexpr int mi2; // expected-error {{requires an initializer}} +}; +// typedef +typedef constexpr int CI; // expected-error {{typedef cannot be constexpr}} +// tag +constexpr class C1 {}; // expected-error {{class cannot be marked constexpr}} +constexpr struct S1 {}; // expected-error {{struct cannot be marked constexpr}} +constexpr union U1 {}; // expected-error {{union cannot be marked constexpr}} +constexpr enum E1 {}; // expected-error {{enum cannot be marked constexpr}} +template constexpr class TC1 {}; // expected-error {{class cannot be marked constexpr}} +template constexpr struct TS1 {}; // expected-error {{struct cannot be marked constexpr}} +template constexpr union TU1 {}; // expected-error {{union cannot be marked constexpr}} +class C2 {} constexpr; // expected-error {{class cannot be marked constexpr}} +struct S2 {} constexpr; // expected-error {{struct cannot be marked constexpr}} +union U2 {} constexpr; // expected-error {{union cannot be marked constexpr}} +enum E2 {} constexpr; // expected-error {{enum cannot be marked constexpr}} +constexpr class C3 {} c3 = C3(); +constexpr struct S3 {} s3 = S3(); +constexpr union U3 {} u3 = {}; +constexpr enum E3 { V3 } e3 = V3; +class C4 {} constexpr c4 = C4(); +struct S4 {} constexpr s4 = S4(); +union U4 {} constexpr u4 = {}; +enum E4 { V4 } constexpr e4 = V4; +constexpr int; // expected-error {{constexpr can only be used in variable and function declarations}} +// redeclaration mismatch +constexpr int f3(); // expected-note {{previous declaration is here}} +int f3(); // expected-error {{non-constexpr declaration of 'f3' follows constexpr declaration}} +int f4(); // expected-note {{previous declaration is here}} +constexpr int f4(); // expected-error {{constexpr declaration of 'f4' follows non-constexpr declaration}} +template constexpr T f5(T); +template constexpr T f5(T); // expected-note {{previous}} +template T f5(T); // expected-error {{non-constexpr declaration of 'f5' follows constexpr declaration}} +template T f6(T); // expected-note {{here}} +template constexpr T f6(T); // expected-error {{constexpr declaration of 'f6' follows non-constexpr declaration}} +// destructor +struct ConstexprDtor { + constexpr ~ConstexprDtor() = default; // expected-error {{destructor cannot be marked constexpr}} +}; + +// template stuff +template constexpr T ft(T t) { return t; } +template T gt(T t) { return t; } +struct S { + template constexpr T f(); + template T g() const; +}; + +// explicit specialization can differ in constepxr +template <> notlit ft(notlit nl) { return nl; } +template <> char ft(char c) { return c; } // expected-note {{previous}} +template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft' follows non-constexpr declaration}} +template <> constexpr int gt(int nl) { return nl; } +template <> notlit S::f() const { return notlit(); } +template <> constexpr int S::g() { return 0; } // expected-note {{previous}} +template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g' follows constexpr declaration}} +// specializations can drop the 'constexpr' but not the implied 'const'. +template <> char S::g() { return 0; } // expected-error {{no function template matches}} +template <> double S::g() const { return 0; } // ok + +constexpr int i3 = ft(1); + +void test() { + // ignore constexpr when instantiating with non-literal + notlit2 nl2; + (void)ft(nl2); +} + +// Examples from the standard: +constexpr int square(int x); // expected-note {{declared here}} +constexpr int bufsz = 1024; + +constexpr struct pixel { // expected-error {{struct cannot be marked constexpr}} + int x; + int y; + constexpr pixel(int); +}; + +constexpr pixel::pixel(int a) + : x(square(a)), y(square(a)) // expected-note {{undefined function 'square' cannot be used in a constant expression}} + { } + +constexpr pixel small(2); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'pixel(2)'}} + +constexpr int square(int x) { + return x * x; +} + +constexpr pixel large(4); + +int next(constexpr int x) { // expected-error {{function parameter cannot be constexpr}} + return x + 1; +} + +extern constexpr int memsz; // expected-error {{constexpr variable declaration must be a definition}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp new file mode 100644 index 0000000..001a086 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - | FileCheck %s + +// constexpr functions and constexpr constructors are implicitly inline. +struct S { + constexpr S(int n); + constexpr int g(); + int n; +}; + +constexpr S::S(int n) : n(n) {} + +constexpr S f(S s) { + return s.n * 2; +} + +constexpr int S::g() { + return f(*this).n; +} + +// CHECK: define linkonce_odr {{.*}} @_Z1f1S( +// CHECK: define linkonce_odr {{.*}} @_ZN1SC1Ei( +// CHECK: define linkonce_odr {{.*}} @_ZNK1S1gEv( + +int g() { + return f(42).g(); +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp new file mode 100644 index 0000000..cafdd63 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -0,0 +1,139 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +namespace N { + typedef char C; +} + +namespace M { + typedef double D; +} + +struct NonLiteral { // expected-note 2{{no constexpr constructors}} + NonLiteral() {} + NonLiteral(int) {} +}; +struct Literal { + constexpr Literal() {} + operator int() const { return 0; } +}; + +struct S { + virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}} +}; +struct SS : S { + int ImplicitlyVirtual() const; +}; + +// The definition of a constexpr function shall satisfy the following +// constraints: +struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}} + constexpr T(); + constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}} + + // - it shall not be virtual; + virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} + + constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} + + // - its return type shall be a literal type; + constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} + constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}} + constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}} + typedef NonLiteral F(); + constexpr F NonLiteralReturn2; // ok until definition + + // - each of its parameter types shall be a literal type; + constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} + typedef int G(NonLiteral); + constexpr G NonLiteralParam2; // ok until definition + + // - its function-body shall be = delete, = default, + constexpr int Deleted() = delete; + // It's not possible for the function-body to legally be "= default" here. + // Other than constructors, only the copy- and move-assignment operators and + // destructor can be defaulted. Destructors can't be constexpr since they + // don't have a literal return type. Defaulted assignment operators can't be + // constexpr since they can't be const. + constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} +}; +struct U { + constexpr U SelfReturn(); + constexpr int SelfParam(U); +}; + +struct V : virtual U { // expected-note {{here}} + constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} +}; + +// or a compound-statememt that contains only +constexpr int AllowedStmts() { + // - null statements + ; + + // - static_assert-declarations + static_assert(true, "the impossible happened!"); + + // - typedef declarations and alias-declarations that do not define classes + // or enumerations + typedef int I; + typedef struct S T; + using J = int; + using K = int[sizeof(I) + sizeof(J)]; + // Note, the standard requires we reject this. + struct U; + + // - using-declarations + using N::C; + + // - using-directives + using namespace N; + + // - and exactly one return statement + return sizeof(K) + sizeof(C) + sizeof(K); +} +constexpr int ForStmt() { + for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}} + return 0; +} +constexpr int VarDecl() { + constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}} + return 0; +} +constexpr int FuncDecl() { + constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}} + return ForwardDecl(42); +} +constexpr int ClassDecl1() { + typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}} + return 0; +} +constexpr int ClassDecl2() { + using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}} + return 0; +} +constexpr int ClassDecl3() { + struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}} + return 0; +} +constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} +constexpr int MultiReturn() { + return 0; // expected-note {{return statement}} + return 0; // expected-error {{multiple return statements in constexpr function}} +} + +// - every constructor call and implicit conversion used in initializing the +// return value shall be one of those allowed in a constant expression. +// +// We implement the proposed resolution of DR1364 and ignore this bullet. +// However, we implement the spirit of the check as part of the p5 checking that +// a constexpr function must be able to produce a constant expression. +namespace DR1364 { + constexpr int f(int k) { + return k; // ok, even though lvalue-to-rvalue conversion of a function + // parameter is not allowed in a constant expression. + } + int kGlobal; // expected-note {{here}} + constexpr int f() { // expected-error {{constexpr function never produces a constant expression}} + return kGlobal; // expected-note {{read of non-const}} + } +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp new file mode 100644 index 0000000..65573c7 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -0,0 +1,249 @@ +// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s + +namespace N { + typedef char C; +} + +namespace M { + typedef double D; +} + +struct NonLiteral { // expected-note 2{{no constexpr constructors}} + NonLiteral() {} + NonLiteral(int) {} +}; +struct Literal { + constexpr Literal() {} + explicit Literal(int); // expected-note 2 {{here}} + operator int() const { return 0; } +}; + +// In the definition of a constexpr constructor, each of the parameter types +// shall be a literal type. +struct S { + constexpr S(int, N::C) {} + constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} + constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} + + // In addition, either its function-body shall be = delete or = default + constexpr S() = default; + constexpr S(Literal) = delete; +}; + +// or it shall satisfy the following constraints: + +// - the class shall not have any virtual base classes; +struct T : virtual S { // expected-note {{here}} + constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} +}; +namespace IndirectVBase { + struct A {}; + struct B : virtual A {}; // expected-note {{here}} + class C : public B { + public: + constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}} + }; +} + +// - its function-body shall not be a function-try-block; +struct U { + constexpr U() + try // expected-error {{function try block not allowed in constexpr constructor}} + : u() { + } catch (...) { + throw; + } + int u; +}; + +// - the compound-statememt of its function-body shall contain only +struct V { + constexpr V() { + // - null statements, + ; + + // - static_assert-declarations, + static_assert(true, "the impossible happened!"); + + // - typedef declarations and alias-declarations that do not define classes + // or enumerations, + typedef int I; + typedef struct S T; + using J = int; + using K = int[sizeof(I) + sizeof(J)]; + // Note, the standard requires we reject this. + struct U; + + // - using-declarations, + using N::C; + + // - and using-directives; + using namespace N; + } + + constexpr V(int(&)[1]) { + for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}} + /**/; + } + constexpr V(int(&)[2]) { + constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}} + } + constexpr V(int(&)[3]) { + constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}} + } + constexpr V(int(&)[4]) { + typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}} + } + constexpr V(int(&)[5]) { + using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}} + } + constexpr V(int(&)[6]) { + struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}} + } + constexpr V(int(&)[7]) { + return; // expected-error {{statement not allowed in constexpr constructor}} + } +}; + +// - every non-static data member and base class sub-object shall be initialized +struct W { + int n; // expected-note {{member not initialized by constructor}} + constexpr W() {} // expected-error {{constexpr constructor must initialize all members}} +}; +struct AnonMembers { + int a; // expected-note {{member not initialized by constructor}} + union { // expected-note 2{{member not initialized by constructor}} + char b; + struct { + double c; + long d; // expected-note {{member not initialized by constructor}} + }; + union { + char e; + void *f; + }; + }; + struct { // expected-note {{member not initialized by constructor}} + long long g; + struct { + int h; // expected-note {{member not initialized by constructor}} + double i; // expected-note {{member not initialized by constructor}} + }; + union { // expected-note 2{{member not initialized by constructor}} + char *j; + AnonMembers *k; + }; + }; + + constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok + // missing d, i, j/k union + constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} // expected-error {{constexpr constructor must initialize all members}} + constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok + // missing h, j/k union + constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} // expected-error {{constexpr constructor must initialize all members}} + // missing b/c/d/e/f union + constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} // expected-error {{constexpr constructor must initialize all members}} + // missing a, b/c/d/e/f union, g/h/i/j/k struct + constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}} +}; + +union Empty { + constexpr Empty() {} // ok +} constexpr empty1; + +struct EmptyVariant { + union {}; + struct {}; + constexpr EmptyVariant() {} // ok +} constexpr empty2; + +template using Int = int; +template +struct TemplateInit { + T a; + int b; // desired-note {{not initialized}} + Int c; // desired-note {{not initialized}} + struct { + T d; + int e; // desired-note {{not initialized}} + Int f; // desired-note {{not initialized}} + }; + struct { + Literal l; + Literal m; + Literal n[3]; + }; + union { // desired-note {{not initialized}} + T g; + T h; + }; + // FIXME: This is ill-formed (no diagnostic required). We should diagnose it. + constexpr TemplateInit() {} // desired-error {{must initialize all members}} +}; +template struct TemplateInit2 { + Literal l; + constexpr TemplateInit2() {} // ok +}; + +template struct weak_ptr { + constexpr weak_ptr() : p(0) {} + T *p; +}; +template struct enable_shared_from_this { + weak_ptr weak_this; + constexpr enable_shared_from_this() {} // ok +}; +constexpr int f(enable_shared_from_this); + +// - every constructor involved in initializing non-static data members and base +// class sub-objects shall be a constexpr constructor. +struct ConstexprBaseMemberCtors : Literal { + Literal l; + + constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok + constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}} + Literal(0), // expected-note {{non-constexpr constructor}} + l() {} + constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}} + l(0) // expected-note {{non-constexpr constructor}} + {} +}; + +// - every assignment-expression that is an initializer-caluse appearing +// directly or indirectly within a brace-or-equal-initializer for a non-static +// data member that is not named by a mem-initializer-id shall be a constant +// expression; and +// +// Note, we deliberately do not implement this bullet, so that we can allow the +// following example. (See N3308). +struct X { + int a = 0; + int b = 2 * a + 1; // ok, not a constant expression. + + constexpr X() {} + constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1 +}; + +// - every implicit conversion used in converting a constructor argument to the +// corresponding parameter type and converting a full-expression to the +// corresponding member type shall be one of those allowed in a constant +// expression. +// +// We implement the proposed resolution of DR1364 and ignore this bullet. +// However, we implement the intent of this wording as part of the p5 check that +// the function must be able to produce a constant expression. +int kGlobal; // expected-note {{here}} +struct Z { + constexpr Z(int a) : n(a) {} + constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}} + int n; +}; + + +namespace StdExample { + struct Length { + explicit constexpr Length(int i = 0) : val(i) { } + private: + int val; + }; +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp new file mode 100644 index 0000000..fd17d35 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fcxx-exceptions %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s + +namespace StdExample { + +constexpr int f(void *) { return 0; } +constexpr int f(...) { return 1; } +constexpr int g1() { return f(0); } +constexpr int g2(int n) { return f(n); } +constexpr int g3(int n) { return f(n*0); } + +namespace N { + constexpr int c = 5; + constexpr int h() { return c; } +} +constexpr int c = 0; +constexpr int g4() { return N::h(); } + +static_assert(f(0) == 0, ""); +static_assert(f('0') == 1, ""); +static_assert(g1() == 0, ""); +static_assert(g2(0) == 1, ""); +static_assert(g2(1) == 1, ""); +static_assert(g3(0) == 1, ""); +static_assert(g3(1) == 1, ""); +static_assert(N::h() == 5, ""); +static_assert(g4() == 5, ""); + + +constexpr int f(bool b) + { return b ? throw 0 : 0; } // ok +constexpr int f() { return throw 0, 0; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{subexpression}} + +struct B { + constexpr B(int x) : i(0) { } + int i; +}; + +int global; // expected-note {{declared here}} + +struct D : B { + constexpr D() : B(global) { } // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}} +}; + +} + +namespace PotentialConstant { + +constexpr int Comma(int n) { return // expected-error {{constexpr function never produces a constant expression}} + (void)(n * 2), + throw 0, // expected-note {{subexpression}} + 0; +} + +int ng; // expected-note 6{{here}} +constexpr int BinaryOp1(int n) { return n + ng; } // expected-error {{never produces}} expected-note {{read}} +constexpr int BinaryOp2(int n) { return ng + n; } // expected-error {{never produces}} expected-note {{read}} + +double dg; // expected-note 2{{here}} +constexpr double BinaryOp1(double d) { return d + dg; } // expected-error {{never produces}} expected-note {{read}} +constexpr double BinaryOp2(double d) { return dg + d; } // expected-error {{never produces}} expected-note {{read}} + +constexpr int Add(int a, int b, int c) { return a + b + c; } +constexpr int FunctionArgs(int a) { return Add(a, ng, a); } // expected-error {{never produces}} expected-note {{read}} + +struct S { int a; int b; int c[2]; }; +constexpr S InitList(int a) { return { a, ng }; }; // expected-error {{never produces}} expected-note {{read}} +constexpr S InitList1a(int a) { return S{ a, ng }; }; // expected-error {{never produces}} expected-note {{read}} +constexpr S InitList2(int a) { return { a, a, { ng } }; }; // expected-error {{never produces}} expected-note {{read}} +constexpr S InitList3(int a) { return a ? S{ a, a } : S{ a, ng }; }; // ok + +constexpr int LogicalAnd1(int n) { return n && (throw, 0); } // ok +constexpr int LogicalAnd2(int n) { return 1 && (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}} + +constexpr int LogicalOr1(int n) { return n || (throw, 0); } // ok +constexpr int LogicalOr2(int n) { return 0 || (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}} + +constexpr int Conditional1(bool b, int n) { return b ? n : ng; } // ok +constexpr int Conditional2(bool b, int n) { return b ? n * ng : n + ng; } // expected-error {{never produces}} expected-note {{both arms of conditional operator are unable to produce a constant expression}} + +// __builtin_constant_p ? : is magical, and is always a potential constant. +constexpr bool BcpCall(int n) { + return __builtin_constant_p((int*)n != &n) ? (int*)n != &n : (int*)n != &n; +} +static_assert(BcpCall(0), ""); + +// DR1311: A function template which can produce a constant expression, but +// for which a particular specialization cannot, is ok. +template constexpr T cmin(T a, T b) { + return a < b ? a : b; +} +int n = cmin(3, 5); // ok + +struct X { + constexpr X() {} + bool operator<(X); // not constexpr +}; + +X x = cmin(X(), X()); // ok, not constexpr + +// Same with other temploids. +template +struct Y { + constexpr Y() {} + constexpr int get() { return T(); } +}; +struct Z { operator int(); }; + +int y1 = Y().get(); // ok +int y2 = Y().get(); // ok + +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp new file mode 100644 index 0000000..1a6dc9e --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +namespace N { + typedef char C; +} + +namespace M { + typedef double D; +} + +struct NonLiteral { + NonLiteral() {} + NonLiteral(int) {} // expected-note 2{{here}} + operator int() const { return 0; } +}; +struct Literal { + constexpr Literal() {} + operator int() const { return 0; } +}; + +struct S { + virtual int ImplicitlyVirtual() const; +}; +struct T {}; + +template struct ImplicitVirtualFromDependentBase : T { + constexpr int ImplicitlyVirtual() { return 0; } +}; + +constexpr int a = ImplicitVirtualFromDependentBase().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}} +constexpr int b = ImplicitVirtualFromDependentBase().ImplicitlyVirtual(); // ok +constexpr int c = ImplicitVirtualFromDependentBase().ImplicitVirtualFromDependentBase::ImplicitlyVirtual(); + +template struct ConstexprMember { + constexpr R F() { return 0; } +}; +constexpr int d = ConstexprMember().F(); // ok +constexpr int e = ConstexprMember().F(); // expected-error {{constant expression}} + +template struct ConstexprCtor { + constexpr ConstexprCtor(P...) {} +}; +constexpr ConstexprCtor<> f1() { return {}; } // ok +constexpr ConstexprCtor f2() { return 0; } // ok +constexpr ConstexprCtor f3() { return { 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}} +constexpr ConstexprCtor f4() { return { 0, 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}} + +struct VirtBase : virtual S {}; // expected-note {{here}} + +namespace TemplateVBase { + template struct T1 : virtual Literal { // expected-note {{here}} + constexpr T1() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} + }; + + template struct T2 : virtual T { + // FIXME: This is ill-formed (no diagnostic required). + // We should diagnose it now rather than waiting until instantiation. + constexpr T2() {} + }; + constexpr T2 g2() { return {}; } + + template class T3 : public T { // expected-note {{class with virtual base class is not a literal type}} + public: + constexpr T3() {} + }; + constexpr T3 g3() { return {}; } // ok + constexpr T3 g4() { return {}; } // expected-error {{not a literal type}} +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp new file mode 100644 index 0000000..c4935b3 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct S { + constexpr int f(); + constexpr int g() const; + static constexpr int Sf(); +}; + +void f(const S &s) { + s.f(); + s.g(); + + int (*f)() = &S::Sf; + int (S::*g)() const = &S::g; +} + +namespace std_example { + + class debug_flag { // expected-note {{not an aggregate and has no constexpr constructors}} + public: + explicit debug_flag(bool); + constexpr bool is_on(); // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}} + private: + bool flag; + }; + + constexpr int bar(int x, int y) // expected-note {{here}} + { return x + y + x*y; } + int bar(int x, int y) // expected-error {{non-constexpr declaration of 'bar' follows constexpr declaration}} + { return x * 2 + 3 * y; } + +} + +// The constexpr specifier is allowed for static member functions of non-literal types. +class NonLiteralClass { + NonLiteralClass(bool); + static constexpr bool isDebugFlag(); +}; diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp new file mode 100644 index 0000000..2412a14 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// A constexpr specifier used in an object declaration declares the object as +// const. +constexpr int a = 0; +extern const int a; + +int i; // expected-note 2{{here}} +constexpr int *b = &i; +extern int *const b; + +constexpr int &c = i; +extern int &c; + +constexpr int (*d)(int) = 0; +extern int (*const d)(int); + +// A variable declaration which uses the constexpr specifier shall have an +// initializer and shall be initialized by a constant expression. +constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}} +constexpr struct C { C(); } ni2; // expected-error {{cannot have non-literal type 'const struct C'}} expected-note 3{{has no constexpr constructors}} +constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}} + +constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} +constexpr C nc2 = C(); // expected-error {{cannot have non-literal type 'const C'}} +int &f(); // expected-note {{declared here}} +constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}} +constexpr int nc4(i); // expected-error {{constexpr variable 'nc4' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} +constexpr C nc5((C())); // expected-error {{cannot have non-literal type 'const C'}} +int &f(); // expected-note {{here}} +constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}} + +struct pixel { + int x, y; +}; +constexpr pixel ur = { 1294, 1024 }; // ok +constexpr pixel origin; // expected-error {{default initialization of an object of const type 'const pixel' requires a user-provided default constructor}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp new file mode 100644 index 0000000..d7b9eff --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -verify %s + +void f0a(void) { + inline void f1(); // expected-error {{inline declaration of 'f1' not allowed in block scope}} +} + +void f0b(void) { + void f1(); +} + +// FIXME: Add test for "If the inline specifier is used in a friend declaration, +// that declaration shall be a definition or the function shall have previously +// been declared inline. diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp new file mode 100644 index 0000000..07eec1e --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -verify %s +// XFAIL: * + +void f0() { +} + +inline void f0(); // expected-error {{function definition cannot precede inline declaration}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp new file mode 100644 index 0000000..ee870d9 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify %s + +class A { +public: + explicit A(); + + explicit operator int(); // expected-warning {{explicit conversion functions are a C++11 extension}} + + explicit void f0(); // expected-error {{'explicit' can only be applied to a constructor or conversion function}} + + operator bool(); +}; + +explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}} +explicit A::operator bool() { return false; } // expected-warning {{explicit conversion functions are a C++11 extension}}\ + // expected-error {{'explicit' can only be specified inside the class definition}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp new file mode 100644 index 0000000..cbb439e --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// A storage-class-specifier shall not be specified in an explicit +// specialization (14.7.3) or an explicit instantiation (14.7.2) +// directive. +template void f(T) {} +template static void g(T) {} + + +template<> static void f(int); // expected-error{{explicit specialization has extraneous, inconsistent storage class 'static'}} +template static void f(float); // expected-error{{explicit instantiation cannot have a storage class}} + +template<> void f(double); +template void f(long); + +template<> static void g(int); // expected-warning{{explicit specialization cannot have a storage class}} +template static void g(float); // expected-error{{explicit instantiation cannot have a storage class}} + +template<> void g(double); +template void g(long); + +template +struct X { + static int value; +}; + +template +int X::value = 17; + +template static int X::value; // expected-error{{explicit instantiation cannot have a storage class}} + +template<> static int X::value; // expected-error{{'static' can only be specified inside the class definition}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp new file mode 100644 index 0000000..fd86276 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -verify %s +// XFAIL: * + +typedef const int T0; +typedef int& T1; + +struct s0 { + mutable const int f0; // expected-error{{'mutable' and 'const' cannot be mixed}} + mutable T0 f1; // expected-error{{'mutable' and 'const' cannot be mixed}} + mutable int &f2; // expected-error{{'mutable' cannot be applied to references}} + mutable T1 f3; // expected-error{{'mutable' cannot be applied to references}} + mutable struct s1 {}; // expected-error{{'mutable' cannot be applied to non-data members}} + mutable void im0(); // expected-error{{'mutable' cannot be applied to functions}} +}; diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp new file mode 100644 index 0000000..44cc5a7 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-compat %s + +// The auto or register specifiers can be applied only to names of objects +// declared in a block (6.3) or to function parameters (8.4). + +auto int ao; // expected-error {{illegal storage class on file-scoped variable}} +auto void af(); // expected-error {{illegal storage class on function}} + +register int ro; // expected-error {{illegal storage class on file-scoped variable}} +register void rf(); // expected-error {{illegal storage class on function}} + +struct S { + auto int ao; // expected-error {{storage class specified for a member declaration}} + auto void af(); // expected-error {{storage class specified for a member declaration}} + + register int ro; // expected-error {{storage class specified for a member declaration}} + register void rf(); // expected-error {{storage class specified for a member declaration}} +}; + +void foo(auto int ap, register int rp) { + auto int abo; + auto void abf(); // expected-error {{illegal storage class on function}} + + register int rbo; + register void rbf(); // expected-error {{illegal storage class on function}} +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp new file mode 100644 index 0000000..491ab17 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -verify %s + +struct S; // expected-note 2{{forward declaration of 'S'}} +extern S a; +extern S f(); // expected-note {{'f' declared here}} +extern void g(S a); + +void h() { + g(a); // expected-error {{argument type 'S' is incomplete}} + f(); // expected-error {{calling 'f' with incomplete return type 'S'}} +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp new file mode 100644 index 0000000..a385aa9 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s -std=c++11 + +struct S { + virtual ~S(); + + void g() throw (auto(*)()->int); + + // Note, this is not permitted: conversion-declarator cannot have a trailing return type. + // FIXME: don't issue the second diagnostic for this. + operator auto(*)()->int(); // expected-error{{'auto' not allowed here}} expected-error {{C++ requires a type specifier}} +}; + +typedef auto Fun(int a) -> decltype(a + a); +typedef auto (*PFun)(int a) -> decltype(a + a); + +void g(auto (*f)() -> int) { + try { } + catch (auto (&f)() -> int) { } + catch (auto (*const f[10])() -> int) { } +} + +namespace std { + class type_info; +} + +template struct U {}; + +void j() { + (void)typeid(auto(*)()->void); + (void)sizeof(auto(*)()->void); + (void)__alignof(auto(*)()->void); + + Uvoid> v; + + int n; + (void)static_castvoid>(&j); + auto p = reinterpret_castint>(&j); + (void)const_castint>(&p); + (void)(auto(*)()->void)(&j); +} + +template void = &j> class C { }; +struct F : auto(*)()->int {}; // expected-error{{expected class name}} +templateint> struct G { }; + +int g(); +auto (*h)() -> auto = &g; // expected-error{{'auto' not allowed in function return type}} +auto (*i)() = &g; // ok; auto deduced as int. +auto (*k)() -> int = i; // ok; no deduction. diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp new file mode 100644 index 0000000..1daf02f --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions -Wc++11-compat +void f() { + auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}} + auto *b = b; // expected-error{{variable 'b' declared with 'auto' type cannot appear in its own initializer}} + const auto c = c; // expected-error{{variable 'c' declared with 'auto' type cannot appear in its own initializer}} + if (auto d = d) {} // expected-error {{variable 'd' declared with 'auto' type cannot appear in its own initializer}} + auto e = ({ auto f = e; 0; }); // expected-error {{variable 'e' declared with 'auto' type cannot appear in its own initializer}} +} + +void g() { + auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}} + + auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}} + + if (auto b) {} // expected-error {{must have an initializer}} + for (;auto b;) {} // expected-error {{must have an initializer}} + while (auto b) {} // expected-error {{must have an initializer}} + if (auto b = true) { (void)b; } +} + +auto n(1,2,3); // expected-error{{initializer for variable 'n' with type 'auto' contains multiple expressions}} + +namespace N +{ + auto a = "const char [16]", *p = &a; +} + +void h() { + auto b = 42ULL; + + for (auto c = 0; c < b; ++c) { + } +} + +template struct same; +template struct same {}; + +void p3example() { + auto x = 5; + const auto *v = &x, u = 6; + static auto y = 0.0; + // In C++98: 'auto' storage class specifier is redundant and incompatible with C++0x + // In C++0x: 'auto' storage class specifier is not permitted in C++0x, and will not be supported in future releases + auto int r; // expected-warning {{'auto' storage class specifier}} + + same<__typeof(x), int> xHasTypeInt; + same<__typeof(v), const int*> vHasTypeConstIntPtr; + same<__typeof(u), const int> uHasTypeConstInt; + same<__typeof(y), double> yHasTypeDouble; +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp new file mode 100644 index 0000000..e566d2a --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions + +template +struct only { + only(T); + template only(U) = delete; +}; + +void f() { + if (auto a = true) { + } + + switch (auto a = 0) { + } + + while (auto a = false) { + } + + for (; auto a = false; ) { + } + + new const auto (0); + new (auto) (0.0); + + int arr[] = {1, 2, 3}; + for (auto i : arr) { + } +} + +class X { + static const auto n = 'x'; + + auto m = 0; // expected-error {{'auto' not allowed in non-static class member}} +}; + +struct S { + static const auto a; // expected-error {{declaration of variable 'a' with type 'auto const' requires an initializer}} + static const auto b = 0; + static const int c; +}; +const int S::b; +const auto S::c = 0; diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp new file mode 100644 index 0000000..71f57dc --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s -std=c++11 + +struct S { + virtual ~S(); + + auto a; // expected-error{{'auto' not allowed in non-static struct member}} + auto *b; // expected-error{{'auto' not allowed in non-static struct member}} + const auto c; // expected-error{{'auto' not allowed in non-static struct member}} + + void f() throw (auto); // expected-error{{'auto' not allowed here}} + + friend auto; // expected-error{{'auto' not allowed in non-static struct member}} + + operator auto(); // expected-error{{'auto' not allowed here}} +}; + +// PR 9278: auto is not allowed in typedefs, except with a trailing return type. +typedef auto *AutoPtr; // expected-error{{'auto' not allowed in typedef}} +typedef auto (*PFun)(int a); // expected-error{{'auto' not allowed in typedef}} +typedef auto Fun(int a) -> decltype(a + a); + +void g(auto a) { // expected-error{{'auto' not allowed in function prototype}} + try { } + catch (auto &a) { } // expected-error{{'auto' not allowed in exception declaration}} + catch (const auto a) { } // expected-error{{'auto' not allowed in exception declaration}} + try { } catch (auto a) { } // expected-error{{'auto' not allowed in exception declaration}} +} + +void h(auto a[10]) { // expected-error{{'auto' not allowed in function prototype}} +} + +void i(const auto a) { // expected-error{{'auto' not allowed in function prototype}} +} + +namespace std { + class type_info; +} + +template struct U {}; + +void j() { + (void)typeid(auto); // expected-error{{'auto' not allowed here}} + (void)sizeof(auto); // expected-error{{'auto' not allowed here}} + (void)__alignof(auto); // expected-error{{'auto' not allowed here}} + + U v; // expected-error{{'auto' not allowed in template argument}} + + int n; + (void)dynamic_cast(n); // expected-error{{'auto' not allowed here}} + (void)static_cast(&n); // expected-error{{'auto' not allowed here}} + (void)reinterpret_cast(&n); // expected-error{{'auto' not allowed here}} + (void)const_cast(n); // expected-error{{'auto' not allowed here}} + (void)*(auto*)(&n); // expected-error{{'auto' not allowed here}} + (void)auto(n); // expected-error{{expected expression}} + (void)auto{n}; // expected-error{{expected expression}} +} + +template class C { }; // expected-error{{'auto' not allowed in template parameter}} +int ints[] = {1, 2, 3}; +template class D { }; // expected-error{{'auto' not allowed in template parameter}} +enum E : auto {}; // expected-error{{'auto' not allowed here}} +struct F : auto {}; // expected-error{{expected class name}} +template struct G { }; // expected-error{{'auto' not allowed in template argument}} + +using A = auto; // expected-error{{'auto' not allowed in type alias}} + +// FIXME: don't issue the second diagnostic for this error. +auto k() -> auto; // expected-error{{'auto' not allowed in function return type}} unexpected-error{{without trailing return type}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp new file mode 100644 index 0000000..d327efc --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions + +template +struct only { + only(T); + template only(U) = delete; +}; + +namespace N +{ + auto a = "const char [16]", *p = &a; + + only testA = a; + only testP = p; +} + +void h() { + auto b = 42ULL; + only testB = b; + + for (auto c = 0; c < 100; ++c) { + only testC = c; + } +} + +void p3example() { + auto x = 5; + const auto *v = &x, u = 6; + static auto y = 0.0; + + only testX = x; + only testV = v; + only testU = u; + only testY = y; +} + +void f() { + if (auto a = true) { + only testA = a; + } + + switch (auto a = 0) { + case 0: + only testA = a; + } + + while (auto a = false) { + only testA = a; + } + + for (; auto a = "test"; ) { + only testA = a; + } + + auto *fail1 = 0; // expected-error {{variable 'fail1' with type 'auto *' has incompatible initializer of type 'int'}} + int **p; + const auto **fail2(p); // expected-error {{variable 'fail2' with type 'auto const **' has incompatible initializer of type 'int **'}} +} + +struct S { + void f(); + char g(int); + float g(double); + int m; + + void test() { + auto p1 = &S::f; + auto S::*p2 = &S::f; + auto (S::*p3)() = &S::f; + auto p4 = &S::g; // expected-error {{incompatible initializer of type ''}} + auto S::*p5 = &S::g; // expected-error {{incompatible initializer of type ''}} + auto (S::*p6)(int) = &S::g; + auto p7 = &S::m; + auto S::*p8 = &S::m; + + only test1 = p1; + only test2 = p2; + only test3 = p3; + only test6 = p6; + only test7 = p7; + only test8 = p8; + } +}; + +namespace PR10939 { + struct X { + int method(int); + int method(float); + }; + + template T g(T); + + void f(X *x) { + auto value = x->method; // expected-error {{reference to non-static member function must be called}} + if (value) { } + + auto funcptr = &g; + int (*funcptr2)(int) = funcptr; + } +} + +// if the initializer is a braced-init-list, deduce auto as std::initializer_list: +// see SemaCXX/cxx0x-initializer-stdinitializerlist.cpp diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp new file mode 100644 index 0000000..9c1d397 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions +void f() { + auto a = 0, b = 0, c = 0; + auto d = 0, e = 0.0; // expected-error {{'int' in declaration of 'd' and deduced as 'double' in declaration of 'e'}} + + auto v1 = 0, *p1 = &v1; + auto *p2 = 0, v2 = *p2; // expected-error {{incompatible initializer}} + + const int k = 0; + auto &f = k, &g = a; // expected-error {{'const int' in declaration of 'f' and deduced as 'int' in declaration of 'g'}} + + typedef int I; + I x; + auto xa = x, xb = 0; + + auto &&ra1 = a, rb1 = b; // expected-error {{'int &' in declaration of 'ra1' and deduced as 'int' in declaration of 'rb1'}} + auto &&ra2 = +a, rb2 = b; +} + +void g() { + auto a = 0, +#if __has_feature(cxx_trailing_return) + (*b)() -> void, +#endif + c = 0; + auto d = 0, // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}} +#if __has_feature(cxx_trailing_return) + (*e)() -> void, +#endif + f = 0.0; +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp new file mode 100644 index 0000000..0271041 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct A { typedef int type; }; +template using X = A; // expected-note {{declared here}} +struct X* p2; // expected-error {{elaborated type refers to a type alias template}} + + +template using Id = T; // expected-note {{declared here}} +template class F> +struct Y { + struct F i; // expected-error {{elaborated type refers to a type alias template}} + typename F::type j; // ok + + // FIXME: don't produce the diagnostic both for the definition and the instantiation. + template using U = F; // expected-note 2{{declared here}} + struct Y::template U k; // expected-error 2{{elaborated type refers to a type alias template}} + typename Y::template U l; // ok +}; +template struct Y; // expected-note {{requested here}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp new file mode 100644 index 0000000..8d58498 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class A {}; // expected-note 4 {{previous use is here}} +enum E {}; + +void a1(struct A); +void a2(class A); +void a3(union A); // expected-error {{use of 'A' with tag type that does not match previous declaration}} +void a4(enum A); // expected-error {{use of 'A' with tag type that does not match previous declaration}} + +class A1 { + friend struct A; + friend class A; + friend union A; // expected-error {{use of 'A' with tag type that does not match previous declaration}} + + friend enum A; // expected-error {{use of 'A' with tag type that does not match previous declaration}} + friend enum E; // expected-warning {{cannot be a friend}} +}; + +template struct B { // expected-note {{previous use is here}} + class Member {}; // expected-note 2 {{previous use is here}} +}; + +template <> class B { + // no type Member +}; + +template <> struct B { + union Member { // expected-note 4 {{previous use is here}} + void* a; + }; +}; + +void b1(struct B); +void b2(class B); +void b3(union B); // expected-error {{use of 'B' with tag type that does not match previous declaration}} +//void b4(enum B); // this just doesn't parse; you can't template an enum directly + +void c1(struct B::Member); +void c2(class B::Member); +void c3(union B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} +void c4(enum B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} + +void d1(struct B::Member); // expected-error {{no struct named 'Member' in 'B'}} +void d2(class B::Member); // expected-error {{no class named 'Member' in 'B'}} +void d3(union B::Member); // expected-error {{no union named 'Member' in 'B'}} +void d4(enum B::Member); // expected-error {{no enum named 'Member' in 'B'}} + +void e1(struct B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} +void e2(class B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} +void e3(union B::Member); +void e4(enum B::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}} + +template struct C { + void foo(class B::Member); // expected-error{{no class named 'Member' in 'B'}} \ + // expected-error{{use of 'Member' with tag type that does not match previous declaration}} +}; + +C f1; +C f2; // expected-note {{in instantiation of template class}} +C f3; // expected-note {{in instantiation of template class}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp new file mode 100644 index 0000000..53227ea --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +const int&& foo(); +int i; +struct A { double x; }; +const A* a = new A(); + +static_assert(is_same::value, ""); +static_assert(is_same::value, ""); +static_assert(is_samex), double>::value, ""); +static_assert(is_samex)), const double&>::value, ""); +static_assert(is_same(i)), int&&>::value, ""); + +int f0(int); // expected-note{{possible target}} +float f0(float); // expected-note{{possible target}} + +decltype(f0) f0_a; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp new file mode 100644 index 0000000..2bd5d23 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +namespace std_example { + +template struct A { ~A() = delete; }; // expected-note {{deleted here}} +template auto h() -> A; +template auto i(T) -> T; +template auto f(T) -> decltype(i(h())); // #1 +template auto f(T) -> void; // #2 +auto g() -> void { + f(42); // ok, calls #2, since #1 is not viable. +} +template auto q(T) -> decltype((h())); +void r() { + // Deduction against q succeeds, but results in a temporary which can't be + // destroyed. + q(42); // expected-error {{attempt to use a deleted function}} +} + +} + +class PD { + friend struct A; + ~PD(); // expected-note 4{{here}} +public: + typedef int n; +}; +struct DD { + ~DD() = delete; // expected-note 2{{here}} + typedef int n; +}; + +struct A { + decltype(PD()) s; // ok + decltype(PD())::n n; // ok + decltype(DD()) *p = new decltype(DD()); // ok +}; + +// Two errors here: one for the decltype, one for the variable. +decltype(PD(), PD()) pd1; // expected-error 2{{private destructor}} +decltype(DD(), DD()) dd1; // expected-error 2{{deleted function}} + +decltype(((13, ((DD())))))::n dd_parens; // ok +decltype(((((42)), PD())))::n pd_parens_comma; // ok + +// Ensure parens aren't stripped from a decltype node. +extern decltype(PD()) pd_ref; // ok +decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD & +decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}} + +namespace libcxx_example { + struct nat { + nat() = delete; + nat(const nat&) = delete; + nat &operator=(const nat&) = delete; + ~nat() = delete; + }; + struct any { + any(...); + }; + + template struct is_same { static const bool value = false; }; + template struct is_same { static const bool value = true; }; + + template T declval(); + + void swap(int &a, int &b); + nat swap(any, any); + + template struct swappable { + typedef decltype(swap(declval(), declval())) type; + static const bool value = !is_same::value; + constexpr operator bool() { return value; } + }; + + static_assert(swappable(), ""); + static_assert(!swappable(), ""); +} + +namespace RequireCompleteType { + template struct S { + static_assert(OK, "boom!"); // expected-error 2{{boom!}} + }; + + template T make(); + template S make(); + void consume(...); + + decltype(make<0, false>()) *p1; // ok + decltype((make<1, false>())) *p2; // ok + + // A complete type is required here in order to detect an overloaded 'operator,'. + decltype(123, make<2, false>()) *p3; // expected-note {{here}} + + decltype(consume(make<3, false>())) *p4; // expected-note {{here}} + + decltype(make())>()) *p5; // ok +} + +namespace Overload { + DD operator+(PD &a, PD &b); + decltype(PD()) *pd_ptr; + decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok + + decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok + DD operator,(int a, PD b); + decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}} +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp new file mode 100644 index 0000000..0b518bb --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fcxx-exceptions + +using X = struct { // ok +}; +template using Y = struct { // expected-error {{can not be defined in a type alias template}} +}; + +class K { + virtual ~K(); + operator struct S {} (); // expected-error{{'K::S' can not be defined in a type specifier}} +}; + +struct A {}; + +void f() { + int arr[3] = {1,2,3}; + + for (struct S { S(int) {} } s : arr) { // expected-error {{types may not be defined in a for range declaration}} + } + + new struct T {}; // expected-error {{'T' can not be defined in a type specifier}} + new struct A {}; // expected-error {{'A' can not be defined in a type specifier}} + + try {} catch (struct U {}) {} // expected-error {{'U' can not be defined in a type specifier}} + + (void)(struct V { V(int); })0; // expected-error {{'V' can not be defined in a type specifier}} + + (void)dynamic_cast((K*)0); // expected-error {{'W' can not be defined in a type specifier}} + (void)static_cast(0); // expected-error {{'X' can not be defined in a type specifier}} + (void)reinterpret_cast(0); // expected-error {{'Y' can not be defined in a type specifier}} + (void)const_cast((const Z*)0); // expected-error {{'Z' can not be defined in a type specifier}} +} + +void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}} +} + +int alignas(struct Aa {}) x; // expected-error {{'Aa' can not be defined in a type specifier}} + +int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}} +int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}} + +namespace std { struct type_info; } +const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' can not be defined in a type specifier}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp new file mode 100644 index 0000000..b06eb01 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp @@ -0,0 +1,160 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +namespace RedeclAliasTypedef { + typedef int T; + using T = int; + using T = int; + typedef T T; + using T = T; + typedef int T; +} + +namespace IllegalTypeIds { + using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}} + using B = inline void(int n); // expected-error {{type name does not allow function specifier}} + using C = virtual void(int n); // expected-error {{type name does not allow function specifier}} + using D = explicit void(int n); // expected-error {{type name does not allow function specifier}} + using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}} + using F = void(*)(int n) &&; // expected-error {{pointer to function type cannot have '&&' qualifier}} + using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}} + using H = constexpr int; // expected-error {{type name does not allow constexpr specifier}} + + using Y = void(int n); // ok + using Z = void(int n) &&; // ok +} + +namespace IllegalSyntax { + using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}} + using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} +} + +namespace VariableLengthArrays { + using T = int[42]; // ok + + int n = 32; + using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}} + + const int m = 42; + using U = int[m]; // expected-note {{previous definition}} + using U = int[42]; // ok + using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}} + + void f() { + int n = 42; + goto foo; // expected-error {{goto into protected scope}} + using T = int[n]; // expected-note {{bypasses initialization of VLA type alias}} + foo: ; + } +} + +namespace RedeclFunc { + int f(int, char**); + using T = int; + T f(int, char **); // ok +} + +namespace LookupFilter { + namespace N { struct S; } + using namespace N; + using S = S*; // ok +} + +namespace InFunctions { + template void f0() { + using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + U u; + } + template void f0(); + + void f1() { + using T = int; + } + void f2() { + using T = int[-1]; // expected-error {{array size is negative}} + } + + template void f3() { // expected-note {{template parameter is declared here}} + using T = int; // expected-error {{declaration of 'T' shadows template parameter}} + } +} + +namespace ClassNameRedecl { + class C0 { + // FIXME: this diagnostic is pretty poor + using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}} + }; + class C1 { + // FIXME: this diagnostic is pretty poor + using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}} + }; + class C2 { + using C0 = C1; // ok + }; + template class C3 { + using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + }; + template class C4 { // expected-note {{template parameter is declared here}} + using T = int; // expected-error {{declaration of 'T' shadows template parameter}} + }; + class C5 { + class c; // expected-note {{previous definition}} + using c = int; // expected-error {{typedef redefinition with different types}} + class d; + using d = d; // ok + }; + class C6 { + class c { using C6 = int; }; // ok + }; +} + +class CtorDtorName { + using X = CtorDtorName; + X(); // expected-error {{expected member name}} + ~X(); // expected-error {{destructor cannot be declared using a type alias}} +}; + +namespace TagName { + using S = struct { int n; }; + using T = class { int n; }; + using U = enum { a, b, c }; + using V = struct V { int n; }; +} + +namespace CWG1044 { + // FIXME: this diagnostic isn't ideal. one diagnostic is enough. + using T = T; // expected-error {{type name requires a specifier}} \ + expected-error {{expected ';' after alias declaration}} +} + +namespace StdExample { + template struct pair; + + using handler_t = void (*)(int); + extern handler_t ignore; + extern void (*ignore)(int); + // FIXME: we know we're parsing a type here; don't recover as if we were + // using operator*. + using cell = pair; // expected-error {{use of undeclared identifier 'cell'}} \ + expected-error {{expected expression}} +} + +namespace Access { + class C0 { + using U = int; // expected-note {{declared private here}} + }; + C0::U v; // expected-error {{'U' is a private member}} + class C1 { + public: + using U = int; + }; + C1::U w; // ok +} + +namespace VoidArg { + using V = void; + V f(int); // ok + V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}} +} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp new file mode 100644 index 0000000..28f49d0 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p3.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -verify %s + +typedef struct s { int x; } s; +typedef int I; +typedef int I2; +typedef I2 I; // expected-note {{previous definition is here}} + +typedef char I; // expected-error {{typedef redefinition with different types}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp new file mode 100644 index 0000000..c16ba20 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify %s + +struct S { + typedef struct A {} A; // expected-note {{previous definition is here}} + typedef struct B B; + typedef A A; // expected-error {{redefinition of 'A'}} + + struct C { }; + typedef struct C OtherC; + typedef OtherC C; + + typedef struct D { } D2; + typedef D2 D; +}; + diff --git a/clang/test/CXX/dcl.dcl/p4-0x.cpp b/clang/test/CXX/dcl.dcl/p4-0x.cpp new file mode 100644 index 0000000..31d4912 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/p4-0x.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only %s + +struct S { + constexpr S(bool b) : b(b) {} + constexpr explicit operator bool() { return b; } + bool b; +}; +struct T { + constexpr operator int() { return 1; } +}; +struct U { + constexpr operator int() { return 1; } // expected-note {{candidate}} + constexpr operator long() { return 0; } // expected-note {{candidate}} +}; + +static_assert(S(true), ""); +static_assert(S(false), "not so fast"); // expected-error {{not so fast}} +static_assert(T(), ""); +static_assert(U(), ""); // expected-error {{ambiguous}} + +static_assert(false, L"\x14hi" "!" R"x(")x"); // expected-error {{static_assert failed L"\024hi!\""}} diff --git a/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp new file mode 100644 index 0000000..06dd1bb --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// An explicitly-defaulted function may be declared constexpr only if it would +// have been implicitly declared as constexpr. +struct S1 { + constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}} + constexpr S1(const S1&) = default; + constexpr S1(S1&&) = default; + constexpr S1 &operator=(const S1&) = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}} + constexpr S1 &operator=(S1&&) = default; // expected-error {{explicitly-defaulted move assignment operator may not have}} + constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}} + int n; +}; +struct NoCopyMove { + constexpr NoCopyMove() {} + NoCopyMove(const NoCopyMove&); + NoCopyMove(NoCopyMove&&); +}; +struct S2 { + constexpr S2() = default; + constexpr S2(const S2&) = default; // expected-error {{defaulted definition of copy constructor is not constexpr}} + constexpr S2(S2&&) = default; // expected-error {{defaulted definition of move constructor is not constexpr}} + NoCopyMove ncm; +}; + +// If a function is explicitly defaulted on its first declaration +// -- it is implicitly considered to be constexpr if the implicit declaration +// would be +struct S3 { + S3() = default; // expected-note {{here}} + S3(const S3&) = default; + S3(S3&&) = default; + constexpr S3(int n) : n(n) {} + int n; +}; +constexpr S3 s3a = S3(0); +constexpr S3 s3b = s3a; +constexpr S3 s3c = S3(); +constexpr S3 s3d; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} + +struct S4 { + S4() = default; + S4(const S4&) = default; // expected-note {{here}} + S4(S4&&) = default; // expected-note {{here}} + NoCopyMove ncm; +}; +constexpr S4 s4a; // ok +constexpr S4 s4b = S4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} +constexpr S4 s4c = s4a; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} + +struct S5 { + constexpr S5(); + int n = 1, m = n + 3; +}; +constexpr S5::S5() = default; +static_assert(S5().m == 4, ""); diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp new file mode 100644 index 0000000..7764980 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// An aggregate is an array or a class... +struct Aggr { +private: + static const int n; + void f(); +protected: + struct Inner { int m; }; +public: + bool &br; // expected-note {{default constructor of 'Aggr' is implicitly deleted because field 'br' of reference type 'bool &' would not be initialized}} +}; +bool b; +Aggr ag = { b }; + +// with no user-provided constructors, ... +struct NonAggr1a { // expected-note 2 {{candidate constructor}} + NonAggr1a(int, int); // expected-note {{candidate constructor}} + int k; +}; +// In C++0x, 'user-provided' is only defined for special member functions, so +// this type is considered to be an aggregate. This is considered to be +// a language defect. +NonAggr1a na1a = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1a'}} + +struct NonAggr1b { + NonAggr1b(const NonAggr1b &); // expected-note {{candidate constructor}} + int k; +}; +NonAggr1b na1b = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1b'}} + +// no brace-or-equal-initializers for non-static data members, ... +struct NonAggr2 { // expected-note 3 {{candidate constructor}} + int m = { 123 }; +}; +NonAggr2 na2 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr2'}} + +// no private... +struct NonAggr3 { // expected-note 3 {{candidate constructor}} +private: + int n; +}; +NonAggr3 na3 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr3'}} + +// or protected non-static data members, ... +struct NonAggr4 { // expected-note 3 {{candidate constructor}} +protected: + int n; +}; +NonAggr4 na4 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr4'}} + +// no base classes, ... +struct NonAggr5 : Aggr { // expected-note 3 {{candidate constructor}} +}; +NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}} +template +struct MaybeAggr5a : BaseList... {}; // expected-note {{default constructor of 'MaybeAggr5a' is implicitly deleted because base class 'Aggr' has a deleted default constructor}} +MaybeAggr5a<> ma5a0 = {}; // ok +MaybeAggr5a ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a'}} + +// and no virtual functions. +struct NonAggr6 { // expected-note 3 {{candidate constructor}} + virtual void f(); + int n; +}; +NonAggr6 na6 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr6'}} + +struct DefaultedAggr { + int n; + + DefaultedAggr() = default; + DefaultedAggr(const DefaultedAggr &) = default; + DefaultedAggr(DefaultedAggr &&) = default; + DefaultedAggr &operator=(const DefaultedAggr &) = default; + DefaultedAggr &operator=(DefaultedAggr &) = default; + ~DefaultedAggr() = default; +}; +DefaultedAggr da = { 42 } ; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp new file mode 100644 index 0000000..1041571 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic -Werror %s +int a1[] = { 1, 3, 5 }; +void f() { + int a2[] = { 1, 3, 5 }; +} +template +void tf() { + T t; + // Element type may be dependent + T a3[] = { 1, 3, 5 }; + // As might be the initializer list, value + int a5[] = { sizeof(T) }; + // or even type. + int a6[] = { t.get() }; +} + +// Allowed by GNU extension +int a4[] = {}; // expected-error {{zero size arrays}} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp new file mode 100644 index 0000000..b30e0ec --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +void f0() { + int &ir = { 17 }; // expected-error{{reference to type 'int' cannot bind to an initializer list}} +} + +namespace PR12453 { + template + void f(int i) { + T x{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \ + // expected-note{{override this message by inserting an explicit cast}} + T y{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \ + // expected-note{{override this message by inserting an explicit cast}} + } + + template void f(int); // expected-note{{in instantiation of function template specialization 'PR12453::f' requested here}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp new file mode 100644 index 0000000..0bea4ed --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// Verify that the appropriate fixits are emitted for narrowing conversions in +// initializer lists. + +typedef short int16_t; + +void fixits() { + int x = 999; + struct {char c;} c2 = {x}; + // CHECK: warning:{{.*}} cannot be narrowed + // CHECK: fix-it:{{.*}}:26}:"static_cast(" + // CHECK: fix-it:{{.*}}:27}:")" + struct {int16_t i;} i16 = {70000}; + // CHECK: warning:{{.*}} cannot be narrowed + // CHECK: fix-it:{{.*}}:30}:"static_cast(" + // CHECK: fix-it:{{.*}}:35}:")" +} + +template +void maybe_shrink_int(T t) { + struct {T t;} t2 = {700}; +} + +void test_template() { + maybe_shrink_int((char)3); + // CHECK: warning:{{.*}} cannot be narrowed + // CHECK: note:{{.*}} in instantiation + // CHECK: note:{{.*}} override + // FIXME: This should be static_cast. + // CHECK: fix-it:{{.*}}"static_cast(" + // CHECK: fix-it:{{.*}}")" +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp new file mode 100644 index 0000000..db20ea6 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -0,0 +1,209 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -verify %s + +// Verify that narrowing conversions in initializer lists cause errors in C++0x +// mode. + +void std_example() { + int x = 999; // x is not a constant expression + const int y = 999; + const int z = 99; + char c1 = x; // OK, though it might narrow (in this case, it does narrow) + char c2{x}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + char c3{y}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + char c4{z}; // OK: no narrowing needed + unsigned char uc1 = {5}; // OK: no narrowing needed + unsigned char uc2 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + unsigned int ui1 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + signed int si1 = + { (unsigned int)-1 }; // expected-error {{ cannot be narrowed }} expected-note {{override}} + int ii = {2.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + float f1 { x }; // expected-error {{ cannot be narrowed }} expected-note {{override}} + float f2 { 7 }; // OK: 7 can be exactly represented as a float + int f(int); + int a[] = + { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level +} + +// Test each rule individually. + +template +struct Agg { + T t; +}; + +template +struct Convert { + constexpr Convert(T v) : v(v) {} + constexpr operator T() const { return v; } + T v; +}; +template Convert ConvertVar(); + +// C++0x [dcl.init.list]p7: A narrowing conversion is an implicit conversion +// +// * from a floating-point type to an integer type, or + +void float_to_int() { + Agg a1 = {1.0F}; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg a2 = {1.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg a3 = {1.0L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + Agg a4 = {f}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg a5 = {d}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg a6 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} +} + +// * from long double to double or float, or from double to float, except where +// the source is a constant expression and the actual value after conversion +// is within the range of values that can be represented (even if it cannot be +// represented exactly), or + +void shrink_float() { + // These aren't constant expressions. + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + + // Variables. + Agg f1 = {f}; // OK (no-op) + Agg f2 = {d}; // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} + Agg f3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // Exact constants. + Agg f4 = {1.0}; // OK (double constant represented exactly) + Agg f5 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constants. + Agg f6 = {0.1}; // OK (double constant in range but rounded) + Agg f7 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constants. + Agg f8 = {1E50}; // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg f9 = {1E50L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; + Agg f10 = {e40 - 5 * e39 + e30 - 5 * e39}; // OK + + // Variables. + Agg d1 = {f}; // OK (widening) + Agg d2 = {d}; // OK (no-op) + Agg d3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // Exact constant. + Agg d4 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constant. + Agg d5 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constant. + Agg d6 = {1E315L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; + Agg d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK + + Agg ce1 = { Convert(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to a floating-point type, +// except where the source is a constant expression and the actual value after +// conversion will fit into the target type and will produce the original +// value when converted back to the original type, or +void int_to_float() { + // Not a constant expression. + char c = 1; + + // Variables. Yes, even though all char's will fit into any floating type. + Agg f1 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg f2 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg f3 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // Constants. + Agg f4 = {12345678}; // OK (exactly fits in a float) + Agg f5 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to an integer type that +// cannot represent all the values of the original type, except where the +// source is a constant expression and the actual value after conversion will +// fit into the target type and will produce the original value when converted +// back to the original type. +void shrink_int() { + // Not a constant expression. + short s = 1; + unsigned short us = 1; + Agg c1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg s1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {us}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // "that cannot represent all the values of the original type" means that the + // validity of the program depends on the relative sizes of integral types. + // This test compiles with -m64, so sizeof(int) i1 = {l1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + long long ll = 1; + Agg l2 = {ll}; // OK + + // Constants. + Agg c2 = {127}; // OK + Agg c3 = {300}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + + Agg i2 = {0x7FFFFFFFU}; // OK + Agg i3 = {0x80000000U}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg i4 = {-0x80000000L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // Bool is also an integer type, but conversions to it are a different AST + // node. + Agg b1 = {0}; // OK + Agg b2 = {1}; // OK + Agg b3 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // Conversions from pointers to booleans aren't narrowing conversions. + Agg b = {&b1}; // OK + + Agg ce1 = { Convert(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} + Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} +} + +// Be sure that type- and value-dependent expressions in templates get the error +// too. + +template +void maybe_shrink_int(T t) { + Agg s1 = {t}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {I}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg t2 = {700}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} +} + +void test_template() { + maybe_shrink_int<15>((int)3); // expected-note {{in instantiation}} + maybe_shrink_int<70000>((char)3); // expected-note {{in instantiation}} +} + + +// We don't want qualifiers on the types in the diagnostic. + +void test_qualifiers(int i) { + const int j = i; + struct {const unsigned char c;} c1 = {j}; // expected-error {{from type 'int' to 'unsigned char' in}} expected-note {{override}} + // Template arguments make it harder to avoid printing qualifiers: + Agg c2 = {j}; // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} +} + +// Test SFINAE checks. +template struct Value { }; + +template +int &check_narrowed(Value); + +template +float &check_narrowed(...); + +void test_narrowed(Value vi, Value vd) { + int &ir = check_narrowed(vd); + float &fr = check_narrowed(vi); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp new file mode 100644 index 0000000..4bcf113 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-error=c++11-narrowing -triple x86_64-apple-macosx10.6.7 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-error=narrowing -triple x86_64-apple-macosx10.6.7 -verify %s + +// Verify that narrowing conversions in initializer lists cause errors in C++0x +// mode. + +void std_example() { + int x = 999; // x is not a constant expression + const int y = 999; + const int z = 99; + char c1 = x; // OK, though it might narrow (in this case, it does narrow) + char c2{x}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + char c3{y}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + char c4{z}; // OK: no narrowing needed + unsigned char uc1 = {5}; // OK: no narrowing needed + unsigned char uc2 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + unsigned int ui1 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + signed int si1 = + { (unsigned int)-1 }; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + int ii = {2.0}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + float f1 { x }; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + float f2 { 7 }; // OK: 7 can be exactly represented as a float + int f(int); + int a[] = + { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level +} + +// Test each rule individually. + +template +struct Agg { + T t; +}; + +template +struct Convert { + constexpr Convert(T v) : v(v) {} + constexpr operator T() const { return v; } + T v; +}; +template Convert ConvertVar(); + +// C++0x [dcl.init.list]p7: A narrowing conversion is an implicit conversion +// +// * from a floating-point type to an integer type, or + +void float_to_int() { + Agg a1 = {1.0F}; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg a2 = {1.0}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg a3 = {1.0L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + Agg a4 = {f}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg a5 = {d}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg a6 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(1.0) }; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-warning {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} +} + +// * from long double to double or float, or from double to float, except where +// the source is a constant expression and the actual value after conversion +// is within the range of values that can be represented (even if it cannot be +// represented exactly), or + +void shrink_float() { + // These aren't constant expressions. + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + + // Variables. + Agg f1 = {f}; // OK (no-op) + Agg f2 = {d}; // expected-warning {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} + Agg f3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // Exact constants. + Agg f4 = {1.0}; // OK (double constant represented exactly) + Agg f5 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constants. + Agg f6 = {0.1}; // OK (double constant in range but rounded) + Agg f7 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constants. + Agg f8 = {1E50}; // expected-warning {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg f9 = {1E50L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; + Agg f10 = {e40 - 5 * e39 + e30 - 5 * e39}; // OK + + // Variables. + Agg d1 = {f}; // OK (widening) + Agg d2 = {d}; // OK (no-op) + Agg d3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // Exact constant. + Agg d4 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constant. + Agg d5 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constant. + Agg d6 = {1E315L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; + Agg d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK + + Agg ce1 = { Convert(1e300) }; // expected-warning {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to a floating-point type, +// except where the source is a constant expression and the actual value after +// conversion will fit into the target type and will produce the original +// value when converted back to the original type, or +void int_to_float() { + // Not a constant expression. + char c = 1; + + // Variables. Yes, even though all char's will fit into any floating type. + Agg f1 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg f2 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg f3 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // Constants. + Agg f4 = {12345678}; // OK (exactly fits in a float) + Agg f5 = {123456789}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(123456789) }; // expected-warning {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to an integer type that +// cannot represent all the values of the original type, except where the +// source is a constant expression and the actual value after conversion will +// fit into the target type and will produce the original value when converted +// back to the original type. +void shrink_int() { + // Not a constant expression. + short s = 1; + unsigned short us = 1; + Agg c1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg s1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {us}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // "that cannot represent all the values of the original type" means that the + // validity of the program depends on the relative sizes of integral types. + // This test compiles with -m64, so sizeof(int) i1 = {l1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + long long ll = 1; + Agg l2 = {ll}; // OK + + // Constants. + Agg c2 = {127}; // OK + Agg c3 = {300}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + + Agg i2 = {0x7FFFFFFFU}; // OK + Agg i3 = {0x80000000U}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg i4 = {-0x80000000L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // Bool is also an integer type, but conversions to it are a different AST + // node. + Agg b1 = {0}; // OK + Agg b2 = {1}; // OK + Agg b3 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // Conversions from pointers to booleans aren't narrowing conversions. + Agg b = {&b1}; // OK + + Agg ce1 = { Convert(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} + Agg ce2 = { ConvertVar() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} +} + +// Be sure that type- and value-dependent expressions in templates get the warning +// too. + +template +void maybe_shrink_int(T t) { + Agg s1 = {t}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {I}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg t2 = {700}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} +} + +void test_template() { + maybe_shrink_int<15>((int)3); // expected-note {{in instantiation}} + maybe_shrink_int<70000>((char)3); // expected-note {{in instantiation}} +} + + +// We don't want qualifiers on the types in the diagnostic. + +void test_qualifiers(int i) { + const int j = i; + struct {const unsigned char c;} c1 = {j}; // expected-warning {{from type 'int' to 'unsigned char' in}} expected-note {{override}} + // Template arguments make it harder to avoid printing qualifiers: + Agg c2 = {j}; // expected-warning {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} +} + +// Make sure we still get the right SFINAE behavior. +template struct Value { }; + +template +int &check_narrowed(Value); + +template +float &check_narrowed(...); + +void test_narrowed(Value vi, Value vd) { + int &ir = check_narrowed(vd); + float &fr = check_narrowed(vi); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp new file mode 100644 index 0000000..885d11b --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR5787 +class C { + public: + ~C() {} +}; + +template +class E { + public: + E& Foo(const C&); + E& Bar() { return Foo(C()); } +}; + +void Test() { + E e; + e.Bar(); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp new file mode 100644 index 0000000..20c059e --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +int g(int); +void f() { + int i; + int& r = i; + r = 1; + int* p = &r; + int &rr=r; + int (&rg)(int) = g; + rg(i); + int a[3]; + int (&ra)[3] = a; + ra[1] = i; +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp new file mode 100644 index 0000000..47e215a --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +int& r1; // expected-error{{declaration of reference variable 'r1' requires an initializer}} +extern int& r2; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp new file mode 100644 index 0000000..adbdff6 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp @@ -0,0 +1,194 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s + +// Test the c++0x-specific reference initialization rules, e.g., the +// rules for rvalue references. +template T prvalue(); +template T&& xvalue(); +template T& lvalue(); + +struct Base { }; +struct Derived : Base { }; + +struct HasArray { + int array[5]; +}; + +int f(int); + +template +struct ConvertsTo { + operator T(); // expected-note 2{{candidate function}} +}; + +void test_rvalue_refs() { + // If the initializer expression... + // - is an xvalue, class prvalue, array prvalue or function lvalue + // and "cv1 T1" is reference-compatible with "cv2 T2", or + + // xvalue case + Base&& base0 = xvalue(); + Base&& base1 = xvalue(); + int&& int0 = xvalue(); + + // class prvalue case + Base&& base2 = prvalue(); + Base&& base3 = prvalue(); + + // array prvalue case + int (&&array0)[5] = HasArray().array; + + // function lvalue case + int (&&function0)(int) = f; + + // - has a class type (i.e., T2 is a class type), where T1 is not + // reference-related to T2, and can be implicitly converted to + // an xvalue, class prvalue, or function lvalue of type "cv3 + // T3", where "cv1 T1" is reference-compatible with "cv3 T3", + + // xvalue + Base&& base4 = ConvertsTo(); + Base&& base5 = ConvertsTo(); + int && int1 = ConvertsTo(); + + // class prvalue + Base&& base6 = ConvertsTo(); + Base&& base7 = ConvertsTo(); + + // function lvalue + int (&&function1)(int) = ConvertsTo(); + + // In the second case, if the reference is an rvalue reference and + // the second standard conversion sequence of the user-defined + // conversion sequence includes an lvalue-to-rvalue conversion, the + // program is ill-formed. + int &&int2 = ConvertsTo(); // expected-error{{no viable conversion from 'ConvertsTo' to 'int'}} + int &&int3 = ConvertsTo(); // expected-error{{no viable conversion from 'ConvertsTo' to 'int'}} +} + +class NonCopyable { + NonCopyable(const NonCopyable&); +}; + +class NonCopyableDerived : public NonCopyable { + NonCopyableDerived(const NonCopyableDerived&); +}; + +// Make sure we get direct bindings with no copies. +void test_direct_binding() { + NonCopyable &&nc0 = prvalue(); + NonCopyable &&nc1 = prvalue(); + NonCopyable &&nc2 = xvalue(); + NonCopyable &&nc3 = xvalue(); + const NonCopyable &nc4 = prvalue(); + const NonCopyable &nc5 = prvalue(); + const NonCopyable &nc6 = xvalue(); + const NonCopyable &nc7 = xvalue(); + NonCopyable &&nc8 = ConvertsTo(); + NonCopyable &&nc9 = ConvertsTo(); + const NonCopyable &nc10 = ConvertsTo(); + const NonCopyable &nc11 = ConvertsTo(); +} + +namespace std_example_1 { + double d = 2.0; + double& rd = d; + const double& rcd = d; + struct A { }; + struct B : A { + operator int&(); + } b; + A& ra = b; + const A& rca = b; + int& ir = B(); +} + +namespace std_example_2 { + double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}} + int i = 2; + double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}} + struct A { }; + struct B : A { } b; + extern B f(); + const A& rca = f(); + A&& rra = f(); + struct X { + operator B(); // expected-note{{candidate function}} + operator int&(); // expected-note{{candidate function}} + } x; + const A& r = x; + int&& rri = static_cast(i); + B&& rrb = x; + int&& rri2 = X(); // expected-error{{no viable conversion from 'std_example_2::X' to 'int'}} + + const double& rcd2 = 2; + double&& rrd = 2; + const volatile int cvi = 1; + const int& r2 = cvi; // expected-error{{binding of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}} + + double d; + double&& rrd2 = d; // expected-error{{rvalue reference to type 'double' cannot bind to lvalue of type 'double'}} + double&& rrd3 = i; +} + +namespace argument_passing { + void base_rvalue_ref(Base&&); + void int_rvalue_ref(int&&); // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo' to 'int &&' for 1st argument}} \ + // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo' to 'int &&' for 1st argument}} + + void array_rvalue_ref(int (&&)[5]); + void function_rvalue_ref(int (&&)(int)); + + void test() { + base_rvalue_ref(xvalue()); + base_rvalue_ref(xvalue()); + int_rvalue_ref(xvalue()); + + base_rvalue_ref(prvalue()); + base_rvalue_ref(prvalue()); + + array_rvalue_ref(HasArray().array); + + function_rvalue_ref(f); + + base_rvalue_ref(ConvertsTo()); + base_rvalue_ref(ConvertsTo()); + int_rvalue_ref(ConvertsTo()); + + base_rvalue_ref(ConvertsTo()); + base_rvalue_ref(ConvertsTo()); + + function_rvalue_ref(ConvertsTo()); + + int_rvalue_ref(ConvertsTo()); // expected-error{{no matching function for call to 'int_rvalue_ref'}} + int_rvalue_ref(ConvertsTo()); // expected-error{{no matching function for call to 'int_rvalue_ref'}} + } + +} + +namespace pr10644 { + struct string { + string(const char* __s); + }; + class map { + int& operator[](const string& __k); + public: + int& operator[](const string&& __k); + }; + void foo() { + static map key_map; + key_map["line"]; + } +} + +namespace PR11003 { + class Value { + }; + struct MoveRef { + operator Value &() const ; + }; + MoveRef Move(int); + void growTo() { + Value x = Move(0); + Value y(Move(0)); + } +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp new file mode 100644 index 0000000..d58a129 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s + +// C++03 requires that we check for a copy constructor when binding a +// reference to a temporary, since we are allowed to make a copy, Even +// though we don't actually make that copy, make sure that we diagnose +// cases where that copy constructor is somehow unavailable. As an +// extension, this is only a warning. + +struct X1 { + X1(); + explicit X1(const X1&); +}; + +struct X2 { + X2(); + +private: + X2(const X2&); // expected-note{{declared private here}} +}; + +struct X3 { + X3(); + +private: + X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}} +}; + +// Check for instantiation of default arguments +template +T get_value_badly() { + double *dp = 0; + // The extension doesn't extend far enough to turn this error into a warning. + T *tp = dp; // expected-error{{cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}} + return T(); +} + +template +struct X4 { + X4(); + X4(const X4&, T = get_value_badly()); // expected-note{{in instantiation of}} +}; + +// Check for "dangerous" default arguments that could cause recursion. +struct X5 { + X5(); + X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} +}; + +void g1(const X1&); +void g2(const X2&); +void g3(const X3&); +void g4(const X4&); +void g5(const X5&); + +void test() { + g1(X1()); + g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private}} + g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}} + g4(X4()); + g5(X5()); // Generates a warning in the default argument. +} + +// Check that unavailable copy constructors still cause SFINAE failures. +template struct int_c { }; + +template T f(const T&); + +// Would be ambiguous with the next g(), except the instantiation failure in +// sizeof() prevents that. +template +int &g(int_c * = 0); + +template float &g(); + +void h() { + float &fp2 = g(); // Not ambiguous. +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp new file mode 100644 index 0000000..27eb6d1 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// C++03 requires that we check for a copy constructor when binding a +// reference to a reference-compatible rvalue, since we are allowed to +// make a copy. C++0x does not permit the copy, so ensure that we +// don't diagnose cases where the copy constructor is unavailable. + +struct X1 { + X1(); + explicit X1(const X1&); +}; + +struct X2 { + X2(); + +private: + X2(const X2&); +}; + +struct X3 { + X3(); + +private: + X3(X3&); +}; + +template +T get_value_badly() { + double *dp = 0; + T *tp = dp; + return T(); +} + +template +struct X4 { + X4(); + X4(const X4&, T = get_value_badly()); +}; + +void g1(const X1&); +void g2(const X2&); +void g3(const X3&); +void g4(const X4&); + +void test() { + g1(X1()); + g2(X2()); + g3(X3()); + g4(X4()); +} + +// Check that unavailable copy constructors do not cause SFINAE failures. +template struct int_c { }; + +template T f(const T&); + +template +int &g(int_c * = 0); // expected-note{{candidate function [with T = X3]}} + +template float &g(); // expected-note{{candidate function [with T = X3]}} + +void h() { + float &fp = g(); // expected-error{{call to 'g' is ambiguous}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp new file mode 100644 index 0000000..08d9639 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s + +// CHECK: example0 +void example0() { + double d = 2.0; + // CHECK: double &rd = + // CHECK-NEXT: DeclRefExpr + double &rd = d; + // CHECK: const double &rcd = + // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue + const double &rcd = d; +} + +struct A { }; +struct B : A { } b; + +// CHECK: example1 +void example1() { + // CHECK: A &ra = + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue + A &ra = b; + // CHECK: const A &rca = + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue + const A& rca = b; +} + +extern B f(); + +struct X { + operator B(); +} x; + +// CHECK: example2 +void example2() { + // CHECK: const A &rca = + // CHECK: ImplicitCastExpr{{.*}}'const struct A' + // CHECK: ImplicitCastExpr{{.*}}'struct A' + // CHECK: CallExpr{{.*}}B + const A &rca = f(); + // CHECK: const A &r = + // CHECK: ImplicitCastExpr{{.*}}'const struct A' + // CHECK: ImplicitCastExpr{{.*}}'struct A' + // CHECK: CXXMemberCallExpr{{.*}}'struct B' + const A& r = x; +} + +// CHECK: example3 +void example3() { + // CHECK: const double &rcd2 = + // CHECK: ImplicitCastExpr{{.*}} + const double& rcd2 = 2; +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp new file mode 100644 index 0000000..fee5f96 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp @@ -0,0 +1,135 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct Base { }; +struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} +struct Unrelated { }; +struct Derived2 : Base { }; +struct Diamond : Derived, Derived2 { }; + +struct ConvertibleToBaseRef { + operator Base&() const; +}; + +struct ConvertibleToDerivedRef { + operator Derived&() const; +}; + +struct ConvertibleToBothDerivedRef { + operator Derived&(); // expected-note{{candidate function}} + operator Derived2&(); // expected-note{{candidate function}} +}; + +struct ConvertibleToIntRef { + operator int&(); +}; + +struct ConvertibleToBase { + operator Base() const; +}; + +struct ConvertibleToDerived { + operator Derived() const; +}; + +struct ConvertibleToBothDerived { + operator Derived(); // expected-note{{candidate function}} + operator Derived2(); // expected-note{{candidate function}} +}; + +struct ConvertibleToInt { + operator int(); +}; + +template T create(); + +// First bullet: lvalue references binding to lvalues (the simple cases). +void bind_lvalue_to_lvalue(Base b, Derived d, + const Base bc, const Derived dc, + Diamond diamond, + int i) { + // Reference-compatible + Base &br1 = b; + Base &br2 = d; + Derived &dr1 = d; + Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'Derived' cannot bind to a value of unrelated type 'Base'}} + Base &br3 = bc; // expected-error{{drops qualifiers}} + Base &br4 = dc; // expected-error{{drops qualifiers}} + Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'Diamond' to base class 'Base':}} + int &ir = i; + long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}} +} + +void bind_lvalue_quals(volatile Base b, volatile Derived d, + volatile const Base bvc, volatile const Derived dvc, + volatile const int ivc) { + volatile Base &bvr1 = b; + volatile Base &bvr2 = d; + volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Base' drops qualifiers}} + volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Derived' drops qualifiers}} + + volatile int &ir = ivc; // expected-error{{binding of reference to type 'volatile int' to a value of type 'const volatile int' drops qualifiers}} + + const volatile Base &bcvr1 = b; + const volatile Base &bcvr2 = d; +} + +void bind_lvalue_to_rvalue() { + Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Base'}} + Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Derived'}} + const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Base'}} + const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Derived'}} + + int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} +} + +void bind_lvalue_to_unrelated(Unrelated ur) { + Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}} + const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a value of unrelated type 'Unrelated'}} +} + +void bind_lvalue_to_conv_lvalue() { + // Not reference-related, but convertible + Base &nbr1 = ConvertibleToBaseRef(); + Base &nbr2 = ConvertibleToDerivedRef(); + Derived &ndr1 = ConvertibleToDerivedRef(); + int &ir = ConvertibleToIntRef(); +} + +void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) { + Derived &dr1 = both; + Base &br1 = both; // expected-error{{reference initialization of type 'Base &' with initializer of type 'ConvertibleToBothDerivedRef' is ambiguous}} +} + +struct IntBitfield { + int i : 17; // expected-note{{bit-field is declared here}} +}; + +void test_bitfield(IntBitfield ib) { + int & ir1 = (ib.i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} +} + +// Second bullet: const lvalue reference binding to an rvalue with +// similar type (both of which are class types). +void bind_const_lvalue_to_rvalue() { + const Base &br1 = create(); + const Base &br2 = create(); + const Derived &dr1 = create(); // expected-error{{no viable conversion}} + + const Base &br3 = create(); + const Base &br4 = create(); + + const Base &br5 = create(); // expected-error{{binding of reference to type 'const Base' to a value of type 'const volatile Base' drops qualifiers}} + const Base &br6 = create(); // expected-error{{binding of reference to type 'const Base' to a value of type 'const volatile Derived' drops qualifiers}} + + const int &ir = create(); +} + +// Second bullet: const lvalue reference binds to the result of a conversion. +void bind_const_lvalue_to_class_conv_temporary() { + const Base &br1 = ConvertibleToBase(); + const Base &br2 = ConvertibleToDerived(); +} +void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) { + const Derived &dr1 = both; + const Base &br1 = both; // expected-error{{reference initialization of type 'const Base &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp new file mode 100644 index 0000000..51d61a5 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR5909 { + struct Foo { + int x : 20; + }; + + bool Test(const int& foo); + + const Foo f = { 0 }; // It compiles without the 'const'. + bool z = Test(f.x); +} + +namespace PR6264 { + typedef int (&T)[3]; + struct S + { + operator T (); + }; + void f() + { + T bar = S(); + } +} + +namespace PR6066 { + struct B { }; + struct A : B { + operator B*(); + operator B&(); // expected-warning{{conversion function converting 'PR6066::A' to its base class 'PR6066::B' will never be used}} + }; + + void f(B&); // no rvalues accepted + void f(B*); + + int g() { + f(A()); // calls f(B*) + return 0; + } +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp new file mode 100644 index 0000000..3631af1 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +char x1[]("hello"); +extern char x1[6]; + +char x2[] = "hello"; +extern char x2[6]; + +char x3[] = { "hello" }; +extern char x3[6]; + +wchar_t x4[](L"hello"); +extern wchar_t x4[6]; + +wchar_t x5[] = L"hello"; +extern wchar_t x5[6]; + +wchar_t x6[] = { L"hello" }; +extern wchar_t x6[6]; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp new file mode 100644 index 0000000..3d67fcc --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +char test1[1]="f"; // expected-error {{initializer-string for char array is too long}} diff --git a/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp new file mode 100644 index 0000000..419f2bf --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct NoDefault { + NoDefault() = delete; // expected-note {{here}} + NoDefault(int); +}; +struct Explicit { // expected-note 2 {{candidate}} expected-note {{here}} + explicit Explicit(int); +}; +struct NoCopy { + NoCopy(); + NoCopy(const NoCopy &) = delete; // expected-note {{here}} +}; +struct NoMove { + NoMove(); + NoMove(NoMove &&) = delete; // expected-note {{here}} +}; +class Private { + Private(int); // expected-note {{here}} +public: + Private(); +}; +class Friend { + friend class S; + Friend(int); +}; + + +class S { + NoDefault nd1; + NoDefault nd2 = 42; + Explicit e1; // expected-note {{here}} + Explicit e2 = 42; // expected-error {{no viable conversion}} + NoCopy nc = NoCopy(); // expected-error {{call to deleted}} + NoMove nm = NoMove(); // expected-error {{call to deleted}} + Private p = 42; // expected-error {{private constructor}} + Friend f = 42; + + S() {} // expected-error {{call to deleted constructor of 'NoDefault'}} \ + expected-error {{must explicitly initialize the member 'e1' which does not have a default constructor}} + S(int) : nd1(42), e1(42) {} +}; + +// FIXME: test the other forms which use copy-initialization diff --git a/clang/test/CXX/dcl.decl/dcl.init/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/p5.cpp new file mode 100644 index 0000000..b50e8d7 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/p5.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: Very incomplete! + +// A program that calls for default-initialization or value-initialization of +// an entity of reference type is illformed. If T is a cv-qualified type, the +// cv-unqualified version of T is used for these definitions of +// zero-initialization, default-initialization, and value-initialization. +// +// FIXME: The diagnostics for these errors are terrible because they fall out +// of the AST representation rather than being explicitly issued during the +// respective initialization forms. +struct S { // expected-error {{implicit default constructor for 'S' must explicitly initialize the reference member}} \ + // expected-note {{candidate constructor (the implicit copy constructor) not viable}} + int& x; // expected-note {{declared here}} +}; +S s; // expected-note {{implicit default constructor for 'S' first required here}} +S f() { + return S(); // expected-error {{no matching constructor for initialization of 'S'}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/p6.cpp b/clang/test/CXX/dcl.decl/dcl.init/p6.cpp new file mode 100644 index 0000000..514fd0c --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/p6.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: Very incomplete! + +// If a program calls for the default initialization of an object of a +// const-qualified type T, T shall be a class type with a +// user-provided default constructor. +struct MakeNonPOD { MakeNonPOD(); }; +struct NoUserDefault : public MakeNonPOD { }; +struct HasUserDefault { HasUserDefault(); }; + +void test_const_default_init() { + const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'const NoUserDefault' requires a user-provided default constructor}} + const HasUserDefault x2; + const int x3; // expected-error{{default initialization of an object of const type 'const int'}} +} + +// rdar://8501008 +struct s0 {}; +struct s1 { static const s0 foo; }; +const struct s0 s1::foo; // expected-error{{default initialization of an object of const type 'const struct s0' requires a user-provided default constructor}} + +template +struct s2 { + static const s0 foo; +}; + +template<> const struct s0 s2::foo; // okay diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp new file mode 100644 index 0000000..102746c --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +void f() { + int b[5]; + auto a[5] = b; // expected-error{{'a' declared as array of 'auto'}} + auto *c[5] = b; // expected-error{{'c' declared as array of 'auto *'}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp new file mode 100644 index 0000000..bb4a48e --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s + +// Simple form +int ar1[10]; + +// Element type cannot be: +// - (cv) void +volatile void ar2[10]; // expected-error {{incomplete element type 'volatile void'}} +// - a reference +int& ar3[10]; // expected-error {{array of references}} +// - a function type +typedef void Fn(); +Fn ar4[10]; // expected-error {{array of functions}} +// - an abstract class +struct Abstract { virtual void fn() = 0; }; // expected-note {{pure virtual}} +Abstract ar5[10]; // expected-error {{abstract class}} + +// If we have a size, it must be greater than zero. +int ar6[-1]; // expected-error {{array with a negative size}} +int ar7[0u]; // expected-warning {{zero size arrays are an extension}} + +// An array with unknown bound is incomplete. +int ar8[]; // expected-error {{needs an explicit size or an initializer}} +// So is an array with an incomplete element type. +struct Incomplete; // expected-note {{forward declaration}} +Incomplete ar9[10]; // expected-error {{incomplete type}} +// Neither of which should be a problem in situations where no complete type +// is required. (PR5048) +void fun(int p1[], Incomplete p2[10]); +extern int ear1[]; +extern Incomplete ear2[10]; + +// cv migrates to element type +typedef const int cint; +extern cint car1[10]; +typedef int intar[10]; +// thus this is a valid redeclaration +extern const intar car1; + +// Check that instantiation works properly when the element type is a template. +template struct S { + typename T::type x; // expected-error {{has no members}} +}; +S ar10[10]; // expected-note {{requested here}} + +// Ensure that negative array size errors include the name of the declared +// array as this is often used to simulate static_assert with template +// instantiations, placing the 'error message' in the declarator name. +int +user_error_message +[-1]; // expected-error {{user_error_message}} +typedef int +another_user_error_message +[-1]; // expected-error {{another_user_error_message}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp new file mode 100644 index 0000000..385e45d --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p10.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + virtual void f(int a = 7); +}; + +struct B : public A { + void f(int a); // expected-note{{'f' declared here}} +}; + +void m() { + B* pb = new B; + A* pa = pb; + pa->f(); // OK, calls pa->B::f(7) + pb->f(); // expected-error{{too few arguments}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp new file mode 100644 index 0000000..0a107eb --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void point(int = 3, int = 4); + +void test_point() { + point(1,2); + point(1); + point(); +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp new file mode 100644 index 0000000..e9c5e0c --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p3.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void nondecl(int (*f)(int x = 5)) // {expected-error {{default arguments can only be specified}}} +{ + void (*f2)(int = 17) // {expected-error {{default arguments can only be specified}}} + = (void (*)(int = 42))f; // {expected-error {{default arguments can only be specified}}} +} + +struct X0 { + int (*f)(int = 17); // expected-error{{default arguments can only be specified for parameters in a function declaration}} + + void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}} +}; diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp new file mode 100644 index 0000000..f3dec52 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f0(int i, int j, int k = 3); +void f0(int i, int j, int k); +void f0(int i, int j = 2, int k); +void f0(int i, int j, int k); +void f0(int i = 1, // expected-note{{previous definition}} + int j, int k); +void f0(int i, int j, int k); + +namespace N0 { + void f0(int, int, int); // expected-note{{candidate}} + + void test_f0_inner_scope() { + f0(); // expected-error{{no matching}} + } +} + +void test_f0_outer_scope() { + f0(); // okay +} + +void f0(int i = 1, // expected-error{{redefinition of default argument}} + int, int); + +template void f1(T); // expected-note{{previous}} + +template +void f1(T = T()); // expected-error{{cannot be added}} + + +namespace N1 { + // example from C++03 standard + // FIXME: make these "f2"s into "f"s, then fix our scoping issues + void f2(int, int); + void f2(int, int = 7); + void h() { + f2(3); // OK, calls f(3, 7) + void f(int = 1, int); // expected-error{{missing default argument}} + } + + void m() + { + void f(int, int); // expected-note{{'f' declared here}} + f(4); // expected-error{{too few arguments to function call}} + void f(int, int = 5); // expected-note{{previous definition}} + f(4); // okay + void f(int, int = 5); // expected-error{{redefinition of default argument}} + } + + void n() + { + f2(6); // okay + } +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp new file mode 100644 index 0000000..3100e56 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p5.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +float global_f; + +void f0(int *ip = &global_f); // expected-error{{cannot initialize}} \ +// expected-note{{passing argument to parameter 'ip' here}} + +// Example from C++03 standard +int a = 1; +int f(int); +int g(int x = f(a)); + +void h() { + a = 2; + { + int *a = 0; + g(); // FIXME: check that a is called with a value of 2 + } +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp new file mode 100644 index 0000000..9ab0b48 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class C { +public: + void f(int i = 3); // expected-note{{here}} + void g(int i, int j = 99); +}; + +void C::f(int i = 3) { } // expected-error{{redefinition of default argument}} + +void C::g(int i = 88, int j) { } + +void test_C(C c) { + c.f(); + c.g(); +} + +template +struct X0 { + void f(int); + + struct Inner { + void g(int); + }; +}; + +// DR217 +template +void X0::f(int = 17) { } // expected-error{{cannot be added}} + +// DR217 + DR205 (reading tea leaves) +template +void X0::Inner::g(int = 17) { } // expected-error{{cannot be added}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp new file mode 100644 index 0000000..164eb36 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void h() +{ + int i; + extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp new file mode 100644 index 0000000..1a08ab7 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +class A { + void f(A* p = this) { } // expected-error{{invalid use of 'this'}} +}; diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp new file mode 100644 index 0000000..a879829 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// FIXME: test with non-std qualifiers + +namespace move { + struct Const { + Const(const Const&&) = default; // expected-error {{the parameter for an explicitly-defaulted move constructor may not be const}} + Const& operator=(const Const&&) = default; // expected-error {{the parameter for an explicitly-defaulted move assignment operator may not be const}} + }; + + struct Volatile { + Volatile(volatile Volatile&&) = default; // expected-error {{the parameter for an explicitly-defaulted move constructor may not be volatile}} + Volatile& operator=(volatile Volatile&&) = default; // expected-error {{the parameter for an explicitly-defaulted move assignment operator may not be volatile}} + }; + + struct AssignmentRet1 { + AssignmentRet1&& operator=(AssignmentRet1&&) = default; // expected-error {{an explicitly-defaulted move assignment operator must return an unqualified lvalue reference to its class type}} + }; + + struct AssignmentRet2 { + const AssignmentRet2& operator=(AssignmentRet2&&) = default; // expected-error {{an explicitly-defaulted move assignment operator must return an unqualified lvalue reference to its class type}} + }; + + struct ConstAssignment { + ConstAssignment& operator=(ConstAssignment&&) const = default; // expected-error {{an explicitly-defaulted move assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} + }; +} + +namespace copy { + struct Volatile { + Volatile(const volatile Volatile&) = default; // expected-error {{the parameter for an explicitly-defaulted copy constructor may not be volatile}} + Volatile& operator=(const volatile Volatile&) = default; // expected-error {{the parameter for an explicitly-defaulted copy assignment operator may not be volatile}} + }; + + struct Const { + Const(const Const&) = default; + Const& operator=(const Const&) = default; + }; + + struct NonConst { + NonConst(NonConst&) = default; + NonConst& operator=(NonConst&) = default; + }; + + struct BadConst { + NonConst nc; // makes implicit copy non-const + BadConst(const BadConst&) = default; // expected-error {{is const, but}} + BadConst& operator=(const BadConst&) = default; // expected-error {{is const, but}} + }; + + struct AssignmentRet1 { + AssignmentRet1&& operator=(const AssignmentRet1&) = default; // expected-error {{an explicitly-defaulted copy assignment operator must return an unqualified lvalue reference to its class type}} + }; + + struct AssignmentRet2 { + const AssignmentRet2& operator=(const AssignmentRet2&) = default; // expected-error {{an explicitly-defaulted copy assignment operator must return an unqualified lvalue reference to its class type}} + }; + + struct ConstAssignment { + ConstAssignment& operator=(const ConstAssignment&) const = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} + }; +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp new file mode 100644 index 0000000..19a5f23 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fcxx-exceptions -fexceptions -verify %s + +// When it is part of a parameter-declaration-clause, the parameter +// pack is a function parameter pack. +template +void f0(Types ...args); + +template +void f1(const Types &...args); + +// [ Note: Otherwise, the parameter-declaration is part of a +// template-parameter-list and the parameter pack is a template +// parameter pack; see 14.1. -- end note ] +template +struct X0 { }; + +template +struct X1 { + template struct Inner; +}; + +// A declarator-id or abstract-declarator containing an ellipsis shall +// only be used in a parameter-declaration. +int (...f2)(int); // expected-error{{only function and template parameters can be parameter packs}} + +void f3() { + int ...x; // expected-error{{only function and template parameters can be parameter packs}} + if (int ...y = 17) { } // expected-error{{only function and template parameters can be parameter packs}} + + for (int ...z = 0; z < 10; ++z) { } // expected-error{{only function and template parameters can be parameter packs}} + + try { + } catch (int ...e) { // expected-error{{only function and template parameters can be parameter packs}} + } +} + +template +struct X2 { + Types ...members; // expected-error{{only function and template parameters can be parameter packs}} \ + // expected-error{{data member type contains unexpanded parameter pack}} +}; + +// The type T of the declarator-id of the function parameter pack +// shall contain a template parameter pack; each template parameter +// pack in T is expanded by the function parameter pack. +template +void f4(T ...args); // expected-error{{type 'T' of function parameter pack does not contain any unexpanded parameter packs}} + diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp new file mode 100644 index 0000000..0e69521 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template struct identity; +template struct tuple; + +template struct is_same { + static const bool value = false; +}; + +template struct is_same { + static const bool value = true; +}; + +// There is a syntactic ambiguity when an ellipsis occurs at the end +// of a parameter-declaration-clause without a preceding comma. In +// this case, the ellipsis is parsed as part of the +// abstract-declarator if the type of the parameter names a template +// parameter pack that has not been expanded; otherwise, it is parsed +// as part of the parameter-declaration-clause. + +template +struct X0 { + typedef identity function_pack_1; + typedef identity variadic_function_pack_1; + typedef identity variadic_1; + typedef tuple template_arg_expansion_1; +}; + + + +// FIXME: Once function parameter packs are implemented, we can test all of the disambiguation diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp new file mode 100644 index 0000000..6b1f3e4 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +auto a() -> int; // ok +const auto b() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not 'auto const'}} +auto *c() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not 'auto *'}} +auto (d() -> int); // expected-error {{trailing return type may not be nested within parentheses}} +auto e() -> auto (*)() -> auto (*)() -> void; // ok: same as void (*(*e())())(); diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp new file mode 100644 index 0000000..ad827fb --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +void f(int) { } // expected-note {{previous definition is here}} +void f(const int) { } // expected-error {{redefinition of 'f'}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp new file mode 100644 index 0000000..2ec1454 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +void f0() &; // expected-error {{non-member function cannot have '&' qualifier}} +void f1() &&; // expected-error {{non-member function cannot have '&&' qualifier}} +void f2() const volatile &&; // expected-error {{non-member function cannot have 'const volatile &&' qualifier}} + +struct X { + void f0() &; + void f1() &&; + static void f2() &; // expected-error{{static member function cannot have '&' qualifier}} + static void f3() &&; // expected-error{{static member function cannot have '&&' qualifier}} +}; + +typedef void func_type_lvalue() &; +typedef void func_type_rvalue() &&; + +typedef func_type_lvalue *func_type_lvalue_ptr; // expected-error{{pointer to function type 'func_type_lvalue' (aka 'void () &') cannot have '&' qualifier}} +typedef func_type_rvalue *func_type_rvalue_ptr; // expected-error{{pointer to function type 'func_type_rvalue' (aka 'void () &&') cannot have '&&' qualifier}} + +typedef func_type_lvalue &func_type_lvalue_ref; // expected-error{{reference to function type 'func_type_lvalue' (aka 'void () &') cannot have '&' qualifier}} +typedef func_type_rvalue &func_type_rvalue_ref; // expected-error{{reference to function type 'func_type_rvalue' (aka 'void () &&') cannot have '&&' qualifier}} + +template struct wrap { + typedef T val; + typedef T *ptr; + typedef T &ref; +}; + +using func_type_lvalue = wrap<>::val; +using func_type_lvalue = wrap::val; +using func_type_rvalue = wrap::val; + +using func_type_lvalue_ptr = wrap<>::ptr; +using func_type_lvalue_ptr = wrap::ptr; +using func_type_rvalue_ptr = wrap::ptr; + +using func_type_lvalue_ref = wrap<>::ref; +using func_type_lvalue_ref = wrap::ref; +using func_type_rvalue_ref = wrap::ref; + +func_type_lvalue f2; // expected-error{{non-member function of type 'func_type_lvalue' (aka 'void () &') cannot have '&' qualifier}} +func_type_rvalue f3; // expected-error{{non-member function of type 'func_type_rvalue' (aka 'void () &&') cannot have '&&' qualifier}} + +struct Y { + func_type_lvalue f0; + func_type_rvalue f1; +}; + +void (X::*mpf1)() & = &X::f0; +void (X::*mpf2)() && = &X::f1; + + +void (f() &&); // expected-error{{non-member function cannot have '&&' qualifier}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp new file mode 100644 index 0000000..e2d94fb --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef void F() const; + +void f() const; // expected-error {{non-member function cannot have 'const' qualifier}} +F g; // expected-error {{non-member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}} + +struct X { + void f() const; + friend void g() const; // expected-error {{non-member function cannot have 'const' qualifier}} + static void h() const; // expected-error {{static member function cannot have 'const' qualifier}} + F i; // ok + friend F j; // expected-error {{non-member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}} + static F k; // expected-error {{static member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}} +}; + +struct Y { + friend void X::f() const; + friend void ::f() const; // expected-error {{non-member function cannot have 'const' qualifier}} +}; diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8-0x.cpp new file mode 100644 index 0000000..11926f1 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8-0x.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +auto f() -> int[32]; // expected-error{{function cannot return array}} +auto g() -> int(int); // expected-error{{function cannot return function}} +auto h() -> auto() -> int; // expected-error{{function cannot return function}} +auto i() -> auto(*)() -> int; diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp new file mode 100644 index 0000000..34a8c85 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { }; +A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}} \ +// expected-error{{out-of-line definition}} +void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}} \ +// expected-error{{out-of-line definition}} + +enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \ +// expected-error{{out-of-line definition}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp new file mode 100644 index 0000000..574a3e7 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +auto j() -> enum { e3 }; // expected-error{{unnamed enumeration must be a definition}} expected-error {{requires a specifier or qualifier}} expected-error {{without trailing return type}} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp new file mode 100644 index 0000000..7e35788 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +class A { +public: + int& i; + + A(int& i) : i(i) { } + + static int s; +}; + +template void ft(T& t) { + t.*&T::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} +} + +void f() { + int b; + A a(b); + + int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'}} + a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}} + + a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} + ft(a); // expected-note{{in instantiation of function template specialization 'ft' requested here}} + + void A::*p = 0; // expected-error{{'p' declared as a member pointer to void}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp new file mode 100644 index 0000000..c02105c --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp @@ -0,0 +1,145 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++ [dcl.ref]p5: +// There shall be no references to references, no arrays of +// references, and no pointers to references. + +// The crazy formatting in here is to enforce the exact report locations. + +typedef int &intref; +typedef intref &intrefref; + +template class RefMem { // expected-warning{{class 'RefMem' does not declare any constructor to initialize its non-modifiable members}} + T + & + member; // expected-note{{reference member 'member' will never be initialized}} +}; + +struct RefRef { + int + & + & // expected-error {{declared as a reference to a reference}} + refref0; + + intref + & + refref1; // collapses + + intrefref + & + refref2; // collapses + + RefMem + < + int + & + > + refref3; // collapses expected-note{{in instantiation of template class 'RefMem' requested here}} +}; + + +template class PtrMem { + T + * // expected-error {{declared as a pointer to a reference}} + member; +}; + +struct RefPtr { + typedef + int + & + * // expected-error {{declared as a pointer to a reference}} + intrefptr; + + typedef + intref + * // expected-error {{declared as a pointer to a reference}} + intrefptr2; + + int + & + * // expected-error {{declared as a pointer to a reference}} + refptr0; + + intref + * // expected-error {{declared as a pointer to a reference}} + refptr1; + + PtrMem + < + int + & + > + refptr2; // expected-note {{in instantiation}} +}; + +template class ArrMem { + T + member + [ // expected-error {{declared as array of references}} + 10 + ]; +}; +template class DepArrMem { + T + member + [ // expected-error {{declared as array of references}} + N + ]; +}; + +struct RefArr { + typedef + int + & + intrefarr + [ // expected-error {{declared as array of references}} + 2 + ]; + + typedef + intref + intrefarr + [ // expected-error {{declared as array of references}} + 2 + ]; + + int + & + refarr0 + [ // expected-error {{declared as array of references}} + 2 + ]; + intref + refarr1 + [ // expected-error {{declared as array of references}} + 2 + ]; + ArrMem + < + int + & + > + refarr2; // expected-note {{in instantiation}} + DepArrMem + < + int + &, + 10 + > + refarr3; // expected-note {{in instantiation}} +}; + + +// The declaration of a reference shall contain an initializer +// (8.5.3) except when the declaration contains an explicit extern +// specifier (7.1.1), is a class member (9.2) declaration within a +// class definition, or is the declaration of a parameter or a +// return type (8.3.5); see 3.1. A reference shall be initialized to +// refer to a valid object or function. [ Note: in particular, a +// null reference cannot exist in a well-defined program, because +// the only way to create such a reference would be to bind it to +// the "object" obtained by dereferencing a null pointer, which +// causes undefined behavior. As described in 9.6, a reference +// cannot be bound directly to a bit-field. + diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp new file mode 100644 index 0000000..4ce80bc --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; +#define JOIN2(X,Y) X##Y +#define JOIN(X,Y) JOIN2(X,Y) +#define CHECK_EQUAL_TYPES(T1, T2) \ + int JOIN(array,__LINE__)[is_same::value? 1 : -1] + +int i; +typedef int& LRI; +typedef int&& RRI; + +typedef LRI& r1; CHECK_EQUAL_TYPES(r1, int&); +typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&); +typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&); + +typedef RRI& r4; CHECK_EQUAL_TYPES(r4, int&); +typedef RRI&& r5; CHECK_EQUAL_TYPES(r5, int&&); diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp new file mode 100644 index 0000000..99334b8 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier. +class foo { + static int i; + void func(); +}; + +int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}} +void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}} +} + + +template +class tfoo { + static int i; + void func(); +}; + +template +int decltype(tfoo())::i; // expected-error{{nested name specifier 'decltype(tfoo())::' for declaration does not refer into a class, class template or class template partial specialization}} +template +void decltype(tfoo())::func() { // expected-error{{nested name specifier 'decltype(tfoo())::' for declaration does not refer into a class, class template or class template partial specialization}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/p1.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/p1.cpp new file mode 100644 index 0000000..3672ea0 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.meaning/p1.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR8019 { + struct x; + template struct x2; + struct y { + struct PR8019::x { int x; }; // expected-error{{non-friend class member 'x' cannot have a qualified name}} + + struct inner; + struct y::inner { }; // expected-warning{{extra qualification on member 'inner'}} + + template + struct PR8019::x2 { }; // expected-error{{non-friend class member 'x2' cannot have a qualified name}} + + template + struct inner_template; + + template + struct y::inner_template { }; // expected-warning{{extra qualification on member 'inner_template'}} + }; + +} + +namespace NS { + void foo(); + extern int bar; + struct X; + template struct Y; + template void wibble(T); +} +namespace NS { + void NS::foo() {} // expected-warning{{extra qualification on member 'foo'}} + int NS::bar; // expected-warning{{extra qualification on member 'bar'}} + struct NS::X { }; // expected-warning{{extra qualification on member 'X'}} + template struct NS::Y; // expected-warning{{extra qualification on member 'Y'}} + template void NS::wibble(T) { } // expected-warning{{extra qualification on member 'wibble'}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.name/p1.cpp b/clang/test/CXX/dcl.decl/dcl.name/p1.cpp new file mode 100644 index 0000000..9838b4f --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.name/p1.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace pr6200 { + struct v {}; + enum E { e }; + struct s { + int i; + operator struct v() { return v(); }; + operator enum E() { return e; } + }; + + void f() + { + // None of these is a declaration. + (void)new struct s; + (void)new enum E; + (void)&s::operator struct v; + (void)&s::operator enum E; + } +} diff --git a/clang/test/CXX/dcl.decl/p4-0x.cpp b/clang/test/CXX/dcl.decl/p4-0x.cpp new file mode 100644 index 0000000..98c33b2 --- /dev/null +++ b/clang/test/CXX/dcl.decl/p4-0x.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct X { + void f() &; + void g() &&; +}; + +void (X::*pmf)() & = &X::f; diff --git a/clang/test/CXX/except/except.handle/p16.cpp b/clang/test/CXX/except/except.handle/p16.cpp new file mode 100644 index 0000000..0810be1 --- /dev/null +++ b/clang/test/CXX/except/except.handle/p16.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s + +// The object declared in an exception-declaration or, if the +// exception-declaration does not specify a name, a temporary (12.2) +// is copy-initialized (8.5) from the exception object. +// +template +class X { + T* ptr; + +public: + X(const X &) { + int *ip = 0; + ptr = ip; // expected-error{{assigning to 'float *' from incompatible type 'int *'}} + } + + ~X() { + float *fp = 0; + ptr = fp; // expected-error{{assigning to 'int *' from incompatible type 'float *'}} + } +}; + +void f() { + try { + } catch (X) { // expected-note{{instantiation}} + // copy constructor + } catch (X xi) { // expected-note{{instantiation}} + // destructor + } +} + +struct Abstract { + virtual void f() = 0; // expected-note{{pure virtual}} +}; + +void g() { + try { + } catch (Abstract) { // expected-error{{variable type 'Abstract' is an abstract class}} + } +} diff --git a/clang/test/CXX/except/except.spec/canonical.cpp b/clang/test/CXX/except/except.spec/canonical.cpp new file mode 100644 index 0000000..81ca2ae --- /dev/null +++ b/clang/test/CXX/except/except.spec/canonical.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// PR10087: Make sure that we don't conflate exception specifications +// from different functions in the canonical type system. +namespace std +{ + +template _Tp&& declval() noexcept; + +template +struct __is_nothrow_constructible +{ + static const bool value = noexcept(_Tp(declval<_Args>()...)); +}; + +template +class basic_string +{ +public: + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + + basic_string() + noexcept(__is_nothrow_constructible::value); +}; + +template +struct __map_value_compare +{ +public: + __map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value); +}; + +struct less +{ +}; + +struct map +{ + typedef __map_value_compare __vc; + __vc vc_; +}; + + +template +basic_string::basic_string() noexcept(__is_nothrow_constructible::value) {} + +template +__map_value_compare::__map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value) {} + +} // std diff --git a/clang/test/CXX/except/except.spec/p1.cpp b/clang/test/CXX/except/except.spec/p1.cpp new file mode 100644 index 0000000..e184ec4 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p1.cpp @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Simple parser tests, dynamic specification. + +namespace dyn { + + struct X { }; + + struct Y { }; + + void f() throw() { } + + void g(int) throw(X) { } + + void h() throw(X, Y) { } + + class Class { + void foo() throw (X, Y) { } + }; + + void (*fptr)() throw(); + +} + +// Simple parser tests, noexcept specification. + +namespace noex { + + void f1() noexcept { } + void f2() noexcept (true) { } + void f3() noexcept (false) { } + void f4() noexcept (1 < 2) { } + + class CA1 { + void foo() noexcept { } + void bar() noexcept (true) { } + }; + + void (*fptr1)() noexcept; + void (*fptr2)() noexcept (true); + +} + +namespace mix { + + void f() throw(int) noexcept { } // expected-error {{cannot have both}} + void g() noexcept throw(int) { } // expected-error {{cannot have both}} + +} + +// Sema tests, noexcept specification + +namespace noex { + + struct A {}; + + void g1() noexcept(A()); // expected-error {{not contextually convertible}} + void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} + +} + +namespace noexcept_unevaluated { + template bool f(T) { + T* x = 1; + } + + template + void g(T x) noexcept((sizeof(T) == sizeof(int)) || noexcept(f(x))) { } + + void h() { + g(1); + } +} + +namespace PR11084 { + template struct A { + static int f() noexcept(1/X) { return 10; } // expected-error{{argument to noexcept specifier must be a constant expression}} expected-note{{division by zero}} + }; + + void g() { A<0>::f(); } // expected-note{{in instantiation of exception specification for 'f' requested here}} +} diff --git a/clang/test/CXX/except/except.spec/p11.cpp b/clang/test/CXX/except/except.spec/p11.cpp new file mode 100644 index 0000000..0e4fad5 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p11.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// This is the "let the user shoot himself in the foot" clause. +void f() noexcept { + throw 0; // no-error +} +void g() throw() { + throw 0; // no-error +} +void h() throw(int) { + throw 0.0; // no-error +} diff --git a/clang/test/CXX/except/except.spec/p14-ir.cpp b/clang/test/CXX/except/except.spec/p14-ir.cpp new file mode 100644 index 0000000..81fbf7d --- /dev/null +++ b/clang/test/CXX/except/except.spec/p14-ir.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - %s | FileCheck %s + +// Copy constructor +struct X0 { + X0(); + X0(const X0 &) throw(); + X0(X0 &); +}; + +struct X1 { + X1(); + X1(const X1 &) throw(); +}; + +struct X2 : X1 { + X2(); +}; +struct X3 : X0, X1 { + X3(); +}; + +struct X4 { + X4(X4 &) throw(); +}; + +struct X5 : X0, X4 { }; + +void test(X2 x2, X3 x3, X5 x5) { + // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr + // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) nounwind + // CHECK-NEXT: ret void + // CHECK-NEXT: } + X2 x2a(x2); + // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr + // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) nounwind + // CHECK-NEXT: ret void + // CHECK-NEXT: } + X3 x3a(x3); + // CHECK: define linkonce_odr void @_ZN2X5C1ERS_({{.*}}) unnamed_addr + // CHECK-NOT: call void @__cxa_call_unexpected + // CHECK: ret void + X5 x5a(x5); +} + +// Default constructor +struct X6 { + X6() throw(); +}; + +struct X7 { + X7(); +}; + +struct X8 : X6 { }; +struct X9 : X6, X7 { }; + +void test() { + // CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X8* %this) unnamed_addr + // CHECK: call void @_ZN2X8C2Ev({{.*}}) nounwind + // CHECK-NEXT: ret void + X8(); + + // CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X9* %this) unnamed_addr + // FIXME: check that this is the end of the line here: + // CHECK: call void @_ZN2X9C2Ev({{.*}}) + // CHECK-NEXT: ret void + X9(); + + // CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X9* %this) unnamed_addr + // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind + // FIXME: and here: + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}}) + // CHECK: ret void + + // CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X8* %this) unnamed_addr + // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind + // CHECK-NEXT: ret void +} diff --git a/clang/test/CXX/except/except.spec/p14.cpp b/clang/test/CXX/except/except.spec/p14.cpp new file mode 100644 index 0000000..8763a70 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p14.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s +struct A { }; +struct B { }; +struct C { }; + +// Destructor +struct X0 { + virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}} +}; +struct X1 { + virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}} +}; +struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}} + +// Copy-assignment operator. +struct CA0 { + CA0 &operator=(const CA0&) throw(A); +}; +struct CA1 { + CA1 &operator=(const CA1&) throw(B); +}; +struct CA2 : CA0, CA1 { }; + +void test_CA() { + CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=; + CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=; + CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}} + CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}} +} + +// In-class member initializers. +struct IC0 { + int inClassInit = 0; +}; +struct IC1 { + int inClassInit = (throw B(), 0); +}; +// FIXME: the exception specification on the default constructor is wrong: +// we cannot currently compute the set of thrown types. +static_assert(noexcept(IC0()), "IC0() does not throw"); +static_assert(!noexcept(IC1()), "IC1() throws"); diff --git a/clang/test/CXX/except/except.spec/p15.cpp b/clang/test/CXX/except/except.spec/p15.cpp new file mode 100644 index 0000000..110ec3f --- /dev/null +++ b/clang/test/CXX/except/except.spec/p15.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Deallocation functions are implicitly noexcept. +// Thus, explicit specs aren't allowed to conflict. + +void f() { + // Force implicit declaration of delete. + delete new int; + delete[] new int[1]; +} + +void operator delete(void*) noexcept; +void operator delete[](void*) noexcept; + +// Same goes for explicit declarations. +void operator delete(void*, float); +void operator delete(void*, float) noexcept; + +void operator delete[](void*, float); +void operator delete[](void*, float) noexcept; + +// But explicit specs stay. +void operator delete(void*, double) throw(int); // expected-note {{previous}} +void operator delete(void*, double) noexcept; // expected-error {{does not match}} diff --git a/clang/test/CXX/except/except.spec/p2-dynamic-types.cpp b/clang/test/CXX/except/except.spec/p2-dynamic-types.cpp new file mode 100644 index 0000000..57f8c32 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p2-dynamic-types.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Dynamic specifications: valid types. + +struct Incomplete; // expected-note 3 {{forward declaration}} + +// Exception spec must not have incomplete types, or pointers to them, except +// void. +void ic1() throw(void); // expected-error {{incomplete type 'void' is not allowed in exception specification}} +void ic2() throw(Incomplete); // expected-error {{incomplete type 'Incomplete' is not allowed in exception specification}} +void ic3() throw(void*); +void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'Incomplete' is not allowed in exception specification}} +void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'Incomplete' is not allowed in exception specification}} + +// Don't suppress errors in template instantiation. +template struct TEx; // expected-note {{template is declared here}} + +void tf() throw(TEx); // expected-error {{implicit instantiation of undefined template}} + +// DR 437, class throws itself. +struct DR437 { + void f() throw(DR437); + void g() throw(DR437*); + void h() throw(DR437&); +}; + +// DR 437 within a nested class +struct DR437_out { + struct DR437_in { + void f() throw(DR437_out); + void g() throw(DR437_out*); + void h() throw(DR437_out&); + }; +}; diff --git a/clang/test/CXX/except/except.spec/p2-places.cpp b/clang/test/CXX/except/except.spec/p2-places.cpp new file mode 100644 index 0000000..67647fb --- /dev/null +++ b/clang/test/CXX/except/except.spec/p2-places.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Tests where specs are allowed and where they aren't. + +namespace dyn { + + // Straight from the standard: + + // Plain function with spec + void f() throw(int); + + // Pointer to function with spec + void (*fp)() throw (int); + + // Function taking reference to function with spec + void g(void pfa() throw(int)); + + // Typedef for pointer to function with spec + typedef int (*pf)() throw(int); // expected-error {{specifications are not allowed in typedefs}} + + // Some more: + + // Function returning function with spec + void (*h())() throw(int); + + // Ultimate parser thrill: function with spec returning function with spec and + // taking pointer to function with spec. + // The actual function throws int, the return type double, the argument float. + void (*i() throw(int))(void (*)() throw(float)) throw(double); + + // Pointer to pointer to function taking function with spec + void (**k)(void pfa() throw(int)); // no-error + + // Pointer to pointer to function with spec + void (**j)() throw(int); // expected-error {{not allowed beyond a single}} + + // Pointer to function returning pointer to pointer to function with spec + void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}} + +} + +namespace noex { + + // These parallel those from above. + + void f() noexcept(false); + + void (*fp)() noexcept(false); + + void g(void pfa() noexcept(false)); + + typedef int (*pf)() noexcept(false); // expected-error {{specifications are not allowed in typedefs}} + + void (*h())() noexcept(false); + + void (*i() noexcept(false))(void (*)() noexcept(true)) noexcept(false); + + void (**k)(void pfa() noexcept(false)); // no-error + + void (**j)() noexcept(false); // expected-error {{not allowed beyond a single}} + + void (**(*h())())() noexcept(false); // expected-error {{not allowed beyond a single}} +} diff --git a/clang/test/CXX/except/except.spec/p3.cpp b/clang/test/CXX/except/except.spec/p3.cpp new file mode 100644 index 0000000..d77aea4 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p3.cpp @@ -0,0 +1,106 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Exception specification compatibility. +// We test function pointers, because functions have an extra rule in p4. + +// Same type is compatible +extern void (*r1)() throw(int); +extern void (*r1)() throw(int); + +// Typedefs don't matter. +typedef int INT; +extern void (*r2)() throw(int); +extern void (*r2)() throw(INT); + +// Order doesn't matter. +extern void (*r3)() throw(int, float); +extern void (*r3)() throw(float, int); + +// MS throw-any spec and no spec at all are compatible +extern void (*r4)(); +extern void (*r4)() throw(...); + +// throw(X) and no spec are not compatible +extern void (*r5)() throw(int); // expected-note {{previous declaration}} +extern void (*r5)(); // expected-error {{exception specification in declaration does not match}} + +// For functions, we accept this with a warning. +extern void f5() throw(int); // expected-note {{previous declaration}} +extern void f5(); // expected-warning {{missing exception specification}} + +// Different types are not compatible. +extern void (*r7)() throw(int); // expected-note {{previous declaration}} +extern void (*r7)() throw(float); // expected-error {{exception specification in declaration does not match}} + +// Top-level const doesn't matter. +extern void (*r8)() throw(int); +extern void (*r8)() throw(const int); + +// Multiple appearances don't matter. +extern void (*r9)() throw(int, int); +extern void (*r9)() throw(int, int); + + +// noexcept is compatible with itself +extern void (*r10)() noexcept; +extern void (*r10)() noexcept; + +// noexcept(true) is compatible with noexcept +extern void (*r11)() noexcept; +extern void (*r11)() noexcept(true); + +// noexcept(false) isn't +extern void (*r12)() noexcept; // expected-note {{previous declaration}} +extern void (*r12)() noexcept(false); // expected-error {{does not match}} + +// The form of the boolean expression doesn't matter. +extern void (*r13)() noexcept(1 < 2); +extern void (*r13)() noexcept(2 > 1); + +// noexcept(false) is incompatible with noexcept(true) +extern void (*r14)() noexcept(true); // expected-note {{previous declaration}} +extern void (*r14)() noexcept(false); // expected-error {{does not match}} + +// noexcept(false) is compatible with itself +extern void (*r15)() noexcept(false); +extern void (*r15)() noexcept(false); + +// noexcept(false) is compatible with MS throw(...) +extern void (*r16)() noexcept(false); +extern void (*r16)() throw(...); + +// noexcept(false) is *not* compatible with no spec +extern void (*r17)(); // expected-note {{previous declaration}} +extern void (*r17)() noexcept(false); // expected-error {{does not match}} + +// except for functions +void f17(); +void f17() noexcept(false); + +// noexcept(false) is compatible with dynamic specs that throw unless +// CWG 1073 resolution is accepted. Clang implements it. +//extern void (*r18)() throw(int); +//extern void (*r18)() noexcept(false); + +// noexcept(true) is compatible with dynamic specs that don't throw +extern void (*r19)() throw(); +extern void (*r19)() noexcept(true); + +// The other way round doesn't work. +extern void (*r20)() throw(); // expected-note {{previous declaration}} +extern void (*r20)() noexcept(false); // expected-error {{does not match}} + +extern void (*r21)() throw(int); // expected-note {{previous declaration}} +extern void (*r21)() noexcept(true); // expected-error {{does not match}} + + +// As a very special workaround, we allow operator new to match no spec +// with a throw(bad_alloc) spec, because C++0x makes an incompatible change +// here. +extern "C++" { namespace std { class bad_alloc {}; } } +typedef decltype(sizeof(int)) mysize_t; +void* operator new(mysize_t) throw(std::bad_alloc); +void* operator new(mysize_t); +void* operator new[](mysize_t); +void* operator new[](mysize_t) throw(std::bad_alloc); + diff --git a/clang/test/CXX/except/except.spec/p5-pointers.cpp b/clang/test/CXX/except/except.spec/p5-pointers.cpp new file mode 100644 index 0000000..dd3c060 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p5-pointers.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Assignment of function pointers. + +struct A +{ +}; + +struct B1 : A +{ +}; + +struct B2 : A +{ +}; + +struct D : B1, B2 +{ +}; + +struct P : private A +{ +}; + +// Some functions to play with below. +void s1() throw(); +void s2() throw(int); +void s3() throw(A); +void s4() throw(B1); +void s5() throw(D); +void s6(); +void s7() throw(int, float); +void (*s8())() throw(B1); // s8 returns a pointer to function with spec +void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec + +void s10() noexcept; +void s11() noexcept(true); +void s12() noexcept(false); + +void fnptrs() +{ + // Assignment and initialization of function pointers. + void (*t1)() throw() = &s1; // valid + t1 = &s2; // expected-error {{not superset}} expected-error {{incompatible type}} + t1 = &s3; // expected-error {{not superset}} expected-error {{incompatible type}} + void (&t2)() throw() = s2; // expected-error {{not superset}} + void (*t3)() throw(int) = &s2; // valid + void (*t4)() throw(A) = &s1; // valid + t4 = &s3; // valid + t4 = &s4; // valid + t4 = &s5; // expected-error {{not superset}} expected-error {{incompatible type}} + void (*t5)() = &s1; // valid + t5 = &s2; // valid + t5 = &s6; // valid + t5 = &s7; // valid + t1 = t3; // expected-error {{not superset}} expected-error {{incompatible type}} + t3 = t1; // valid + void (*t6)() throw(B1); + t6 = t4; // expected-error {{not superset}} expected-error {{incompatible type}} + t4 = t6; // valid + t5 = t1; // valid + t1 = t5; // expected-error {{not superset}} expected-error {{incompatible type}} + + // return types and arguments must match exactly, no inheritance allowed + void (*(*t7)())() throw(B1) = &s8; // valid + void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}} + void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}} + void (*t10)(void (*)() throw(B1)) = &s9; // valid expected-warning{{disambiguated}} + void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}} + void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}} +} + +// Member function stuff + +struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}} +void Str1::f() // expected-warning {{missing exception specification}} +{ +} + +void mfnptr() +{ + void (Str1::*pfn1)() throw(int) = &Str1::f; // valid + void (Str1::*pfn2)() = &Str1::f; // valid + void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} +} diff --git a/clang/test/CXX/except/except.spec/p5-virtual.cpp b/clang/test/CXX/except/except.spec/p5-virtual.cpp new file mode 100644 index 0000000..69daec6 --- /dev/null +++ b/clang/test/CXX/except/except.spec/p5-virtual.cpp @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Compatibility of virtual functions. + +struct A +{ +}; + +struct B1 : A +{ +}; + +struct B2 : A +{ +}; + +struct D : B1, B2 +{ +}; + +struct P : private A +{ +}; + +struct Base +{ + virtual void f1() throw(); + virtual void f2() throw(int, float); + + virtual void f3() throw(int, float); + virtual void f4() throw(A); + virtual void f5() throw(A, int, float); + virtual void f6(); + + virtual void f7() noexcept; + virtual void f8() noexcept; + virtual void f9() noexcept(false); + virtual void f10() noexcept(false); + + virtual void f11() throw(); + virtual void f12() noexcept; + virtual void f13() noexcept(false); + virtual void f14() throw(int); + + virtual void f15(); + virtual void f16(); + + virtual void g1() throw(); // expected-note {{overridden virtual function is here}} + virtual void g2() throw(int); // expected-note {{overridden virtual function is here}} + virtual void g3() throw(A); // expected-note {{overridden virtual function is here}} + virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}} + virtual void g5() throw(A); // expected-note {{overridden virtual function is here}} + + virtual void g6() noexcept; // expected-note {{overridden virtual function is here}} + virtual void g7() noexcept; // expected-note {{overridden virtual function is here}} + + virtual void g8() noexcept; // expected-note {{overridden virtual function is here}} + virtual void g9() throw(); // expected-note {{overridden virtual function is here}} + virtual void g10() throw(int); // expected-note {{overridden virtual function is here}} +}; +struct Derived : Base +{ + virtual void f1() throw(); + virtual void f2() throw(float, int); + + virtual void f3() throw(float); + virtual void f4() throw(B1); + virtual void f5() throw(B1, B2, int); + virtual void f6() throw(B2, B2, int, float, char, double, bool); + + virtual void f7() noexcept; + virtual void f8() noexcept(true); + virtual void f9() noexcept(true); + virtual void f10() noexcept(false); + + virtual void f11() noexcept; + virtual void f12() throw(); + virtual void f13() throw(int); + virtual void f14() noexcept(true); + + virtual void f15() noexcept; + virtual void f16() throw(); + + virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}} + virtual void g2(); // expected-error {{exception specification of overriding function is more lax}} + virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}} + virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}} + virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}} + + virtual void g6() noexcept(false); // expected-error {{exception specification of overriding function is more lax}} + virtual void g7(); // expected-error {{exception specification of overriding function is more lax}} + + virtual void g8() throw(int); // expected-error {{exception specification of overriding function is more lax}} + virtual void g9() noexcept(false); // expected-error {{exception specification of overriding function is more lax}} + virtual void g10() noexcept(false); // expected-error {{exception specification of overriding function is more lax}} +}; diff --git a/clang/test/CXX/except/except.spec/p9-dynamic.cpp b/clang/test/CXX/except/except.spec/p9-dynamic.cpp new file mode 100644 index 0000000..4559e0d --- /dev/null +++ b/clang/test/CXX/except/except.spec/p9-dynamic.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +void external(); + +void target() throw(int) +{ + // CHECK: invoke void @_Z8externalv() + external(); +} +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK-NEXT: filter [1 x i8*] [i8* bitcast (i8** @_ZTIi to i8*)] +// CHECK: call void @__cxa_call_unexpected diff --git a/clang/test/CXX/except/except.spec/p9-noexcept.cpp b/clang/test/CXX/except/except.spec/p9-noexcept.cpp new file mode 100644 index 0000000..7c8d0ef --- /dev/null +++ b/clang/test/CXX/except/except.spec/p9-noexcept.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +void external(); + +void target() noexcept +{ + // CHECK: invoke void @_Z8externalv() + external(); +} +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK-NEXT: catch i8* null +// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind +// CHECK-NEXT: unreachable + +void reverse() noexcept(false) +{ + // CHECK: call void @_Z8externalv() + external(); +} diff --git a/clang/test/CXX/except/except.spec/template.cpp b/clang/test/CXX/except/except.spec/template.cpp new file mode 100644 index 0000000..805a604 --- /dev/null +++ b/clang/test/CXX/except/except.spec/template.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// We use pointer assignment compatibility to test instantiation. + +template void f1() throw(int); +template void f2() noexcept(N > 1); + +void (*t1)() throw(int) = &f1<0>; +void (*t2)() throw() = &f1<0>; // expected-error {{not superset}} + +void (*t3)() noexcept = &f2<2>; // no-error +void (*t4)() noexcept = &f2<0>; // expected-error {{not superset}} diff --git a/clang/test/CXX/expr/expr.ass/p9-cxx11.cpp b/clang/test/CXX/expr/expr.ass/p9-cxx11.cpp new file mode 100644 index 0000000..206c82c --- /dev/null +++ b/clang/test/CXX/expr/expr.ass/p9-cxx11.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +template struct complex { + complex(T = T(), T = T()); + void operator+=(complex); + T a, b; +}; + +void std_example() { + complex z; + z = { 1, 2 }; + z += { 1, 2 }; + + int a, b; + a = b = { 1 }; + a = { 1 } = b; // expected-error {{initializer list cannot be used on the left hand side of operator '='}} + a = a + { 4 }; // expected-error {{initializer list cannot be used on the right hand side of operator '+'}} + a = { 3 } * { 4 }; // expected-error {{initializer list cannot be used on the left hand side of operator '*'}} \ + expected-error {{initializer list cannot be used on the right hand side of operator '*'}} +} + +struct S { + constexpr S(int a, int b) : a(a), b(b) {} + int a, b; +}; +struct T { + constexpr int operator=(S s) { return s.a; } + constexpr int operator+=(S s) { return s.b; } +}; +static_assert((T() = {4, 9}) == 4, ""); +static_assert((T() += {4, 9}) == 9, ""); + +int k1 = T() = { 1, 2 } = { 3, 4 }; // expected-error {{initializer list cannot be used on the left hand side of operator '='}} +int k2 = T() = { 1, 2 } + 1; // expected-error {{initializer list cannot be used on the left hand side of operator '+'}} diff --git a/clang/test/CXX/expr/expr.cast/p4-0x.cpp b/clang/test/CXX/expr/expr.cast/p4-0x.cpp new file mode 100644 index 0000000..96bf5f9 --- /dev/null +++ b/clang/test/CXX/expr/expr.cast/p4-0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct X { }; +struct Y : X { }; + +void test_lvalue_to_rvalue_drop_cvquals(const X &x, const Y &y, const int &i) { + (void)(X&&)x; + (void)(int&&)i; + (void)(X&&)y; + (void)(Y&&)x; +} diff --git a/clang/test/CXX/expr/expr.cast/p4.cpp b/clang/test/CXX/expr/expr.cast/p4.cpp new file mode 100644 index 0000000..907e008 --- /dev/null +++ b/clang/test/CXX/expr/expr.cast/p4.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -ast-dump %s | FileCheck %s + +struct A { int x; }; +struct B { int y; }; +struct C : A, B { }; + +// CHECK: casting_away_constness +void casting_away_constness(const B &b, const C &c, const B *bp, const C *cp) { + // CHECK: DerivedToBase (B) + // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'c' + (void)(B&)c; + // CHECK: BaseToDerived (B) + // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'b' + (void)(C&)b; + // CHECK: DerivedToBase (B) + // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'cp' + (void)(B*)cp; + // CHECK: BaseToDerived (B) + // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'bp' + (void)(C*)bp; + // CHECK: ReturnStmt + return; +} diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp new file mode 100644 index 0000000..054669e --- /dev/null +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -0,0 +1,596 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -pedantic -verify -fcxx-exceptions %s -fconstexpr-depth 128 -triple i686-pc-linux-gnu + +// A conditional-expression is a core constant expression unless it involves one +// of the following as a potentially evaluated subexpression [...]: + +// - this (5.1.1 [expr.prim.general]) [Note: when evaluating a constant +// expression, function invocation substitution (7.1.5 [dcl.constexpr]) +// replaces each occurrence of this in a constexpr member function with a +// pointer to the class object. -end note]; +struct This { + int this1 : this1; // expected-error {{undeclared}} + int this2 : this->this1; // expected-error {{invalid}} + void this3() { + int n1[this->this1]; // expected-warning {{variable length array}} + int n2[this1]; // expected-warning {{variable length array}} + (void)n1, (void)n2; + } +}; + +// - an invocation of a function other than a constexpr constructor for a +// literal class or a constexpr function [ Note: Overload resolution (13.3) +// is applied as usual - end note ]; +struct NonConstexpr1 { + static int f() { return 1; } // expected-note {{here}} + int n : f(); // expected-error {{constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}} +}; +struct NonConstexpr2 { + constexpr NonConstexpr2(); // expected-note {{here}} + int n; +}; +struct NonConstexpr3 { + NonConstexpr3(); + int m : NonConstexpr2().n; // expected-error {{constant expression}} expected-note {{undefined constructor 'NonConstexpr2'}} +}; +struct NonConstexpr4 { + NonConstexpr4(); // expected-note {{declared here}} + int n; +}; +struct NonConstexpr5 { + int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4' cannot be used in a constant expression}} +}; + +// - an invocation of an undefined constexpr function or an undefined +// constexpr constructor; +struct UndefinedConstexpr { + constexpr UndefinedConstexpr(); + static constexpr int undefinedConstexpr1(); // expected-note {{here}} + int undefinedConstexpr2 : undefinedConstexpr1(); // expected-error {{constant expression}} expected-note {{undefined function 'undefinedConstexpr1' cannot be used in a constant expression}} +}; + +// - an invocation of a constexpr function with arguments that, when substituted +// by function invocation substitution (7.1.5), do not produce a core constant +// expression; +namespace NonConstExprReturn { + static constexpr const int &id_ref(const int &n) { + return n; + } + struct NonConstExprFunction { + int n : id_ref(16); // ok + }; + constexpr const int *address_of(const int &a) { + return &a; + } + constexpr const int *return_param(int n) { // expected-note {{declared here}} + return address_of(n); + } + struct S { + int n : *return_param(0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}} + }; +} + +// - an invocation of a constexpr constructor with arguments that, when +// substituted by function invocation substitution (7.1.5), do not produce all +// constant expressions for the constructor calls and full-expressions in the +// mem-initializers (including conversions); +namespace NonConstExprCtor { + struct T { + constexpr T(const int &r) : + r(r) { + } + const int &r; + }; + constexpr int n = 0; + constexpr T t1(n); // ok + constexpr T t2(0); // expected-error {{must be initialized by a constant expression}} expected-note {{temporary created here}} expected-note {{reference to temporary is not a constant expression}} + + struct S { + int n : T(4).r; // ok + }; +} + +// - an invocation of a constexpr function or a constexpr constructor that would +// exceed the implementation-defined recursion limits (see Annex B); +namespace RecursionLimits { + constexpr int RecurseForever(int n) { + return n + RecurseForever(n+1); // expected-note {{constexpr evaluation exceeded maximum depth of 128 calls}} expected-note 9{{in call to 'RecurseForever(}} expected-note {{skipping 118 calls}} + } + struct AlsoRecurseForever { + constexpr AlsoRecurseForever(int n) : + n(AlsoRecurseForever(n+1).n) // expected-note {{constexpr evaluation exceeded maximum depth of 128 calls}} expected-note 9{{in call to 'AlsoRecurseForever(}} expected-note {{skipping 118 calls}} + {} + int n; + }; + struct S { + int k : RecurseForever(0); // expected-error {{constant expression}} expected-note {{in call to}} + int l : AlsoRecurseForever(0).n; // expected-error {{constant expression}} expected-note {{in call to}} + }; +} + +// DR1458: taking the address of an object of incomplete class type +namespace IncompleteClassTypeAddr { + struct S; + extern S s; + constexpr S *p = &s; // ok + static_assert(p, ""); + + extern S sArr[]; + constexpr S (*p2)[] = &sArr; // ok + + struct S { + constexpr S *operator&() { return nullptr; } + }; + constexpr S *q = &s; // ok + static_assert(!q, ""); +} + +// - an operation that would have undefined behavior [Note: including, for +// example, signed integer overflow (Clause 5 [expr]), certain pointer +// arithmetic (5.7 [expr.add]), division by zero (5.6 [expr.mul]), or certain +// shift operations (5.8 [expr.shift]) -end note]; +namespace UndefinedBehavior { + void f(int n) { + switch (n) { + case (int)4.4e9: // expected-error {{constant expression}} expected-note {{value 4.4E+9 is outside the range of representable values of type 'int'}} + case (int)0x80000000u: // ok + case (int)10000000000ll: // expected-note {{here}} + case (unsigned int)10000000000ll: // expected-error {{duplicate case value}} + case (int)(unsigned)(long long)4.4e9: // ok + case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}} + case (int)((float)1e37 / 1e30): // ok + case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type 'half'}} + break; + } + } + + constexpr int int_min = ~0x7fffffff; + constexpr int minus_int_min = -int_min; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} + constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}} + constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}} + constexpr int int_min_div_minus_1 = int_min / -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} + constexpr int int_min_mod_minus_1 = int_min % -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} + + constexpr int shl_m1 = 0 << -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}} + constexpr int shl_0 = 0 << 0; // ok + constexpr int shl_31 = 0 << 31; // ok + constexpr int shl_32 = 0 << 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type 'int' (32}} expected-warning {{>= width of type}} + constexpr int shl_unsigned_negative = unsigned(-3) << 1; // ok + constexpr int shl_unsigned_into_sign = 1u << 31; // ok + constexpr int shl_unsigned_overflow = 1024u << 31; // ok + constexpr int shl_signed_negative = (-3) << 1; // expected-error {{constant expression}} expected-note {{left shift of negative value -3}} + constexpr int shl_signed_ok = 1 << 30; // ok + constexpr int shl_signed_into_sign = 1 << 31; // ok (DR1457) + constexpr int shl_signed_into_sign_2 = 0x7fffffff << 1; // ok (DR1457) + constexpr int shl_signed_off_end = 2 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{signed shift result (0x100000000) requires 34 bits to represent, but 'int' only has 32 bits}} + constexpr int shl_signed_off_end_2 = 0x7fffffff << 2; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{signed shift result (0x1FFFFFFFC) requires 34 bits to represent, but 'int' only has 32 bits}} + constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{requires 43 bits to represent}} + constexpr int shl_signed_ok2 = 1024 << 20; // ok + + constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}} + constexpr int shr_0 = 0 >> 0; // ok + constexpr int shr_31 = 0 >> 31; // ok + constexpr int shr_32 = 0 >> 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type}} expected-warning {{>= width of type}} + + struct S { + int m; + }; + constexpr S s = { 5 }; + constexpr const int *p = &s.m + 1; + constexpr const int &f(const int *q) { + return q[0]; + } + constexpr int n = (f(p), 0); // ok + struct T { + int n : f(p); // expected-error {{not an integral constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} + }; + + namespace Ptr { + struct A {}; + struct B : A { int n; }; + B a[3][3]; + constexpr B *p = a[0] + 4; // expected-error {{constant expression}} expected-note {{element 4 of array of 3 elements}} + B b = {}; + constexpr A *pa = &b + 1; // expected-error {{constant expression}} expected-note {{base class of pointer past the end}} + constexpr B *pb = (B*)((A*)&b + 1); // expected-error {{constant expression}} expected-note {{derived class of pointer past the end}} + constexpr const int *pn = &(&b + 1)->n; // expected-error {{constant expression}} expected-note {{field of pointer past the end}} + constexpr B *parr = &a[3][0]; // expected-error {{constant expression}} expected-note {{array element of pointer past the end}} + + constexpr A *na = nullptr; + constexpr B *nb = nullptr; + constexpr A &ra = *nb; // expected-error {{constant expression}} expected-note {{cannot access base class of null pointer}} + constexpr B &rb = (B&)*na; // expected-error {{constant expression}} expected-note {{cannot access derived class of null pointer}} + static_assert((A*)nb == 0, ""); + static_assert((B*)na == 0, ""); + constexpr const int &nf = nb->n; // expected-error {{constant expression}} expected-note {{cannot access field of null pointer}} + constexpr const int &np = (*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot access array element of null pointer}} + + struct C { + constexpr int f() { return 0; } + } constexpr c = C(); + constexpr int k1 = c.f(); // ok + constexpr int k2 = ((C*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{cannot call member function on null pointer}} + constexpr int k3 = (&c)[1].f(); // expected-error {{constant expression}} expected-note {{cannot call member function on pointer past the end of object}} + C c2; + constexpr int k4 = c2.f(); // ok! + + constexpr int diff1 = &a[2] - &a[0]; + constexpr int diff2 = &a[1][3] - &a[1][0]; + constexpr int diff3 = &a[2][0] - &a[1][0]; // expected-error {{constant expression}} expected-note {{subtracted pointers are not elements of the same array}} + static_assert(&a[2][0] == &a[1][3], ""); + constexpr int diff4 = (&b + 1) - &b; + constexpr int diff5 = &a[1][2].n - &a[1][0].n; // expected-error {{constant expression}} expected-note {{subtracted pointers are not elements of the same array}} + constexpr int diff6 = &a[1][2].n - &a[1][2].n; + constexpr int diff7 = (A*)&a[0][1] - (A*)&a[0][0]; // expected-error {{constant expression}} expected-note {{subtracted pointers are not elements of the same array}} + } + + namespace Overflow { + // Signed int overflow. + constexpr int n1 = 2 * 3 * 3 * 7 * 11 * 31 * 151 * 331; // ok + constexpr int n2 = 65536 * 32768; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range of }} + constexpr int n3 = n1 + 1; // ok + constexpr int n4 = n3 + 1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range of }} + constexpr int n5 = -65536 * 32768; // ok + constexpr int n6 = 3 * -715827883; // expected-error {{constant expression}} expected-note {{value -2147483649 is outside the range of }} + constexpr int n7 = -n3 + -1; // ok + constexpr int n8 = -1 + n7; // expected-error {{constant expression}} expected-note {{value -2147483649 is outside the range of }} + constexpr int n9 = n3 - 0; // ok + constexpr int n10 = n3 - -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range of }} + constexpr int n11 = -1 - n3; // ok + constexpr int n12 = -2 - n3; // expected-error {{constant expression}} expected-note {{value -2147483649 is outside the range of }} + constexpr int n13 = n5 + n5; // expected-error {{constant expression}} expected-note {{value -4294967296 is outside the range of }} + constexpr int n14 = n3 - n5; // expected-error {{constant expression}} expected-note {{value 4294967295 is outside the range of }} + constexpr int n15 = n5 * n5; // expected-error {{constant expression}} expected-note {{value 4611686018427387904 is outside the range of }} + constexpr signed char c1 = 100 * 2; // ok + constexpr signed char c2 = '\x64' * '\2'; // also ok + constexpr long long ll1 = 0x7fffffffffffffff; // ok + constexpr long long ll2 = ll1 + 1; // expected-error {{constant}} expected-note {{ 9223372036854775808 }} + constexpr long long ll3 = -ll1 - 1; // ok + constexpr long long ll4 = ll3 - 1; // expected-error {{constant}} expected-note {{ -9223372036854775809 }} + constexpr long long ll5 = ll3 * ll3; // expected-error {{constant}} expected-note {{ 85070591730234615865843651857942052864 }} + + // Yikes. + char melchizedek[2200000000]; + typedef decltype(melchizedek[1] - melchizedek[0]) ptrdiff_t; + constexpr ptrdiff_t d1 = &melchizedek[0x7fffffff] - &melchizedek[0]; // ok + constexpr ptrdiff_t d2 = &melchizedek[0x80000000u] - &melchizedek[0]; // expected-error {{constant expression}} expected-note {{ 2147483648 }} + constexpr ptrdiff_t d3 = &melchizedek[0] - &melchizedek[0x80000000u]; // ok + constexpr ptrdiff_t d4 = &melchizedek[0] - &melchizedek[0x80000001u]; // expected-error {{constant expression}} expected-note {{ -2147483649 }} + + // Unsigned int overflow. + static_assert(65536u * 65536u == 0u, ""); // ok + static_assert(4294967295u + 1u == 0u, ""); // ok + static_assert(0u - 1u == 4294967295u, ""); // ok + static_assert(~0u * ~0u == 1u, ""); // ok + + // Floating-point overflow and NaN. + constexpr float f1 = 1e38f * 3.4028f; // ok + constexpr float f2 = 1e38f * 3.4029f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}} + constexpr float f3 = 1e38f / -.2939f; // ok + constexpr float f4 = 1e38f / -.2938f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}} + constexpr float f5 = 2e38f + 2e38f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}} + constexpr float f6 = -2e38f - 2e38f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces an infinity}} + constexpr float f7 = 0.f / 0.f; // expected-error {{constant expression}} expected-note {{floating point arithmetic produces a NaN}} + } +} + +// - a lambda-expression (5.1.2); +struct Lambda { + // FIXME: clang crashes when trying to parse this! Revisit this check once + // lambdas are fully implemented. + //int n : []{ return 1; }(); +}; + +// - an lvalue-to-rvalue conversion (4.1) unless it is applied to +namespace LValueToRValue { + // - a non-volatile glvalue of integral or enumeration type that refers to a + // non-volatile const object with a preceding initialization, initialized + // with a constant expression [Note: a string literal (2.14.5 [lex.string]) + // corresponds to an array of such objects. -end note], or + volatile const int vi = 1; // expected-note 2{{here}} + const int ci = 1; + volatile const int &vrci = ci; + static_assert(vi, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} + static_assert(const_cast(vi), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vi'}} + static_assert(vrci, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} + + // - a non-volatile glvalue of literal type that refers to a non-volatile + // object defined with constexpr, or that refers to a sub-object of such an + // object, or + struct V { + constexpr V() : v(1) {} + volatile int v; // expected-note {{not literal because}} + }; + constexpr V v; // expected-error {{non-literal type}} + struct S { + constexpr S(int=0) : i(1), v(const_cast(vi)) {} + constexpr S(const S &s) : i(2), v(const_cast(vi)) {} + int i; + volatile int &v; + }; + constexpr S s; // ok + constexpr volatile S vs; // expected-note {{here}} + constexpr const volatile S &vrs = s; // ok + static_assert(s.i, ""); + static_assert(s.v, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} + static_assert(const_cast(s.v), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vi'}} + static_assert(vs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} + static_assert(const_cast(vs.i), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vs'}} + static_assert(vrs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} + + // - a non-volatile glvalue of literal type that refers to a non-volatile + // temporary object whose lifetime has not ended, initialized with a + // constant expression; + constexpr volatile S f() { return S(); } + static_assert(f().i, ""); // ok! there's no lvalue-to-rvalue conversion here! + static_assert(((volatile const S&&)(S)0).i, ""); // expected-error {{constant expression}} +} + +// DR1312: The proposed wording for this defect has issues, so we ignore this +// bullet and instead prohibit casts from pointers to cv void (see core-20842 +// and core-20845). +// +// - an lvalue-to-rvalue conversion (4.1 [conv.lval]) that is applied to a +// glvalue of type cv1 T that refers to an object of type cv2 U, where T and U +// are neither the same type nor similar types (4.4 [conv.qual]); + +// - an lvalue-to-rvalue conversion (4.1) that is applied to a glvalue that +// refers to a non-active member of a union or a subobject thereof; +namespace LValueToRValueUnion { + // test/SemaCXX/constant-expression-cxx11.cpp contains more thorough testing + // of this. + union U { int a, b; } constexpr u = U(); + static_assert(u.a == 0, ""); + constexpr const int *bp = &u.b; + constexpr int b = *bp; // expected-error {{constant expression}} expected-note {{read of member 'b' of union with active member 'a'}} + + extern const U pu; + constexpr const int *pua = &pu.a; + constexpr const int *pub = &pu.b; + constexpr U pu = { .b = 1 }; // expected-warning {{C99 feature}} + constexpr const int a2 = *pua; // expected-error {{constant expression}} expected-note {{read of member 'a' of union with active member 'b'}} + constexpr const int b2 = *pub; // ok +} + +// - an id-expression that refers to a variable or data member of reference type +// unless the reference has a preceding initialization, initialized with a +// constant expression; +namespace References { + const int a = 2; + int &b = *const_cast(&a); + int c = 10; // expected-note 2 {{here}} + int &d = c; + constexpr int e = 42; + int &f = const_cast(e); + extern int &g; + constexpr int &h(); // expected-note {{here}} + int &i = h(); // expected-note {{here}} + constexpr int &j() { return b; } + int &k = j(); + + struct S { + int A : a; + int B : b; + int C : c; // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} + int D : d; // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} + int D2 : &d - &c + 1; + int E : e / 2; + int F : f - 11; + int G : g; // expected-error {{constant expression}} + int H : h(); // expected-error {{constant expression}} expected-note {{undefined function 'h'}} + int I : i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}} + int J : j(); + int K : k; + }; +} + +// - a dynamic_cast (5.2.7); +namespace DynamicCast { + struct S { int n; }; + constexpr S s { 16 }; + struct T { + int n : dynamic_cast(&s)->n; // expected-warning {{constant expression}} expected-note {{dynamic_cast}} + }; +} + +// - a reinterpret_cast (5.2.10); +namespace ReinterpretCast { + struct S { int n; }; + constexpr S s { 16 }; + struct T { + int n : reinterpret_cast(&s)->n; // expected-warning {{constant expression}} expected-note {{reinterpret_cast}} + }; + struct U { + int m : (long)(S*)6; // expected-warning {{constant expression}} expected-note {{reinterpret_cast}} + }; +} + +// - a pseudo-destructor call (5.2.4); +namespace PseudoDtor { + int k; + typedef int I; + struct T { + int n : (k.~I(), 0); // expected-error {{constant expression}} + }; +} + +// - increment or decrement operations (5.2.6, 5.3.2); +namespace IncDec { + int k = 2; + struct T { + int n : ++k; // expected-error {{constant expression}} + int m : --k; // expected-error {{constant expression}} + }; +} + +// - a typeid expression (5.2.8) whose operand is of a polymorphic class type; +namespace std { + struct type_info { + virtual ~type_info(); + const char *name; + }; +} +namespace TypeId { + struct S { virtual void f(); }; + constexpr S *p = 0; + constexpr const std::type_info &ti1 = typeid(*p); // expected-error {{must be initialized by a constant expression}} expected-note {{typeid applied to expression of polymorphic type 'TypeId::S'}} + + struct T {} t; + constexpr const std::type_info &ti2 = typeid(t); +} + +// - a new-expression (5.3.4); +// - a delete-expression (5.3.5); +namespace NewDelete { + int *p = 0; + struct T { + int n : *new int(4); // expected-error {{constant expression}} + int m : (delete p, 2); // expected-error {{constant expression}} + }; +} + +// - a relational (5.9) or equality (5.10) operator where the result is +// unspecified; +namespace UnspecifiedRelations { + int a, b; + constexpr int *p = &a, *q = &b; + // C++11 [expr.rel]p2: If two pointers p and q of the same type point to + // different objects that are not members of the same array or to different + // functions, or if only one of them is null, the results of pq, p<=q, + // and p>=q are unspecified. + constexpr bool u1 = p < q; // expected-error {{constant expression}} + constexpr bool u2 = p > q; // expected-error {{constant expression}} + constexpr bool u3 = p <= q; // expected-error {{constant expression}} + constexpr bool u4 = p >= q; // expected-error {{constant expression}} + constexpr bool u5 = p < 0; // expected-error {{constant expression}} + constexpr bool u6 = p <= 0; // expected-error {{constant expression}} + constexpr bool u7 = p > 0; // expected-error {{constant expression}} + constexpr bool u8 = p >= 0; // expected-error {{constant expression}} + constexpr bool u9 = 0 < q; // expected-error {{constant expression}} + constexpr bool u10 = 0 <= q; // expected-error {{constant expression}} + constexpr bool u11 = 0 > q; // expected-error {{constant expression}} + constexpr bool u12 = 0 >= q; // expected-error {{constant expression}} + void f(), g(); + + constexpr void (*pf)() = &f, (*pg)() = &g; + constexpr bool u13 = pf < pg; // expected-error {{constant expression}} + constexpr bool u14 = pf == pg; + + // If two pointers point to non-static data members of the same object with + // different access control, the result is unspecified. + struct A { + public: + constexpr A() : a(0), b(0) {} + int a; + constexpr bool cmp() { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}} + private: + int b; + }; + class B { + public: + A a; + constexpr bool cmp() { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}} + protected: + A b; + }; + + // If two pointers point to different base sub-objects of the same object, or + // one points to a base subobject and the other points to a member, the result + // of the comparison is unspecified. This is not explicitly called out by + // [expr.rel]p2, but is covered by 'Other pointer comparisons are + // unspecified'. + struct C { + int c[2]; + }; + struct D { + int d; + }; + struct E : C, D { + struct Inner { + int f; + } e; + } e; + constexpr bool base1 = &e.c[0] < &e.d; // expected-error {{constant expression}} expected-note {{comparison of addresses of subobjects of different base classes has unspecified value}} + constexpr bool base2 = &e.c[1] < &e.e.f; // expected-error {{constant expression}} expected-note {{comparison of address of base class subobject 'C' of class 'E' to field 'e' has unspecified value}} + constexpr bool base3 = &e.e.f < &e.d; // expected-error {{constant expression}} expected-note {{comparison of address of base class subobject 'D' of class 'E' to field 'e' has unspecified value}} + + // [expr.rel]p3: Pointers to void can be compared [...] if both pointers + // represent the same address or are both the null pointer [...]; otherwise + // the result is unspecified. + struct S { int a, b; } s; + constexpr void *null = 0; + constexpr void *pv = (void*)&s.a; + constexpr void *qv = (void*)&s.b; + constexpr bool v1 = null < 0; + constexpr bool v2 = null < pv; // expected-error {{constant expression}} + constexpr bool v3 = null == pv; // ok + constexpr bool v4 = qv == pv; // ok + constexpr bool v5 = qv >= pv; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} + constexpr bool v6 = qv > null; // expected-error {{constant expression}} + constexpr bool v7 = qv <= (void*)&s.b; // ok + constexpr bool v8 = qv > (void*)&s.a; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} +} + +// - an assignment or a compound assignment (5.17); or +namespace Assignment { + int k; + struct T { + int n : (k = 9); // expected-error {{constant expression}} + int m : (k *= 2); // expected-error {{constant expression}} + }; + + struct Literal { + constexpr Literal(const char *name) : name(name) {} + const char *name; + }; + struct Expr { + constexpr Expr(Literal l) : IsLiteral(true), l(l) {} + bool IsLiteral; + union { + Literal l; + // ... + }; + }; + struct MulEq { + constexpr MulEq(Expr a, Expr b) : LHS(a), RHS(b) {} + Expr LHS; + Expr RHS; + }; + constexpr MulEq operator*=(Expr a, Expr b) { return MulEq(a, b); } + Literal a("a"); + Literal b("b"); + MulEq c = a *= b; // ok +} + +// - a throw-expression (15.1) +namespace Throw { + struct S { + int n : (throw "hello", 10); // expected-error {{constant expression}} + }; +} + +// PR9999 +template +class bitWidthHolding { +public: + static const + unsigned int width = (v == 0 ? 0 : bitWidthHolding<(v >> 1)>::width + 1); +}; + +static const int width=bitWidthHolding<255>::width; + +template +struct always_false { + static const bool value = false; +}; + +template +struct and_or { + static const bool and_value = b && and_or::value>::and_value; + static const bool or_value = !b || and_or::value>::or_value; +}; + +static const bool and_value = and_or::and_value; +static const bool or_value = and_or::or_value; + +static_assert(and_value == false, ""); +static_assert(or_value == true, ""); diff --git a/clang/test/CXX/expr/expr.const/p3-0x-nowarn.cpp b/clang/test/CXX/expr/expr.const/p3-0x-nowarn.cpp new file mode 100644 index 0000000..c891374 --- /dev/null +++ b/clang/test/CXX/expr/expr.const/p3-0x-nowarn.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-c++11-narrowing -verify %s + +// +void f(int x) { + switch (x) { + case 0x80000001: break; + } +} diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp new file mode 100644 index 0000000..6ddd11b --- /dev/null +++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +// A converted constant expression of type T is a core constant expression, +int nonconst = 8; // expected-note 3 {{here}} +enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}} +template struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} +void NonConstF() { + switch (nonconst) { + case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}} + break; + } + return; +} + +// implicitly converted to a prvalue of type T, where the converted expression +// is a literal constant expression + +bool a(int n) { + constexpr char vowels[] = "aeiou"; + switch (n) { + case vowels[0]: + case vowels[1]: + case vowels[2]: + case vowels[3]: + case vowels[4]: + static_assert(!vowels[5], "unexpected number of vowels"); + return true; + } + return false; +} + +// and the implicit conversion sequence contains only +// +// user-defined conversions, +struct S { constexpr operator int() const { return 5; } }; +enum E : unsigned char { E5 = S(), E6, E10 = S() * 2, E1 = E5 / 5 }; + +// lvalue-to-rvalue conversions, +const E e10 = E10; +template struct T {}; +T s10; + +// integral promotions, and +enum class EE { EE32 = ' ', EE65 = 'A', EE1 = (short)1, EE5 = E5 }; + +// integral conversions other than narrowing conversions +int b(unsigned n) { + switch (n) { + case E6: + case EE::EE32: // expected-error {{not implicitly convertible}} + case (int)EE::EE32: + case 1000: + case (long long)1e10: // expected-error {{case value evaluates to 10000000000, which cannot be narrowed to type 'unsigned int'}} + case -3: // expected-error {{case value evaluates to -3, which cannot be narrowed to type 'unsigned int'}} + return n; + } + return 0; +} +enum class EEE : unsigned short { + a = E6, + b = EE::EE32, // expected-error {{not implicitly convertible}} + c = (int)EE::EE32, + d = 1000, + e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}} + f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}} +}; +template using A = int; +using Int = A; +using Int = A; // expected-error {{not implicitly convertible}} +using Int = A<(int)EE::EE32>; +using Int = A<200>; +using Int = A<1000>; // expected-error {{template argument evaluates to 1000, which cannot be narrowed to type 'unsigned char'}} +using Int = A<-3>; // expected-error {{template argument evaluates to -3, which cannot be narrowed to type 'unsigned char'}} + +// Note, conversions from integral or unscoped enumeration types to bool are +// integral conversions as well as boolean conversions. +template struct Val { static constexpr T value = v; }; +static_assert(Val::value == 1, ""); // ok +static_assert(Val::value == 0, ""); // ok +static_assert(Val::value == 1, ""); // ok +static_assert(Val::value == 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}} + +// (no other conversions are permitted) +using Int = A<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}} +enum B : bool { + True = &a, // expected-error {{conversion from 'bool (*)(int)' to 'bool' is not allowed in a converted constant expression}} + False = nullptr // expected-error {{conversion from 'nullptr_t' to 'bool' is not allowed in a converted constant expression}} +}; +void c() { + // Note, promoted type of switch is 'int'. + switch (bool b = a(5)) { // expected-warning {{boolean value}} + case 0.0f: // expected-error {{conversion from 'float' to 'int' is not allowed in a converted constant expression}} + break; + } +} +template int f() { return B; } +template int f<&S::operator int>(); // expected-error {{does not refer to a function template}} +template int f<(bool)&S::operator int>(); + +int n = Val::value; // expected-error {{conversion from 'int (S::*)() const' to 'bool' is not allowed in a converted constant expression}} + +namespace NonConstLValue { + struct S { + constexpr operator int() { return 10; } + }; + S s; // not constexpr + // Under the FDIS, this is not a converted constant expression. + // Under the new proposed wording, it is. + enum E : char { e = s }; +} diff --git a/clang/test/CXX/expr/expr.const/p5-0x.cpp b/clang/test/CXX/expr/expr.const/p5-0x.cpp new file mode 100644 index 0000000..60fabe3 --- /dev/null +++ b/clang/test/CXX/expr/expr.const/p5-0x.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +// If an expression of literal class type is used in a context where an integral +// constant expression is required, then that class type shall have a single +// non-explicit conversion function to an integral or unscoped enumeration type +namespace std_example { + +struct A { + constexpr A(int i) : val(i) { } + constexpr operator int() { return val; } + constexpr operator long() { return 43; } +private: + int val; +}; +template struct X { }; +constexpr A a = 42; +X x; // ok, unique conversion to int +int ary[a]; // expected-error {{size of array has non-integer type 'const std_example::A'}} + +} + +struct OK { + constexpr OK() {} + constexpr operator int() { return 8; } +} constexpr ok; +extern struct Incomplete incomplete; // expected-note 4{{forward decl}} +struct Explicit { + constexpr Explicit() {} + constexpr explicit operator int() { return 4; } // expected-note 4{{here}} +} constexpr expl; +struct Ambiguous { + constexpr Ambiguous() {} + constexpr operator int() { return 2; } // expected-note 4{{here}} + constexpr operator long() { return 1; } // expected-note 4{{here}} +} constexpr ambig; + +constexpr int test_ok = ok; // ok +constexpr int test_explicit(expl); // ok +constexpr int test_ambiguous = ambig; // ok + +static_assert(test_ok == 8, ""); +static_assert(test_explicit == 4, ""); +static_assert(test_ambiguous == 2, ""); + +// [expr.new]p6: Every constant-expression in a noptr-new-declarator shall be +// an integral constant expression +auto new1 = new int[1][ok]; +auto new2 = new int[1][incomplete]; // expected-error {{incomplete}} +auto new3 = new int[1][expl]; // expected-error {{explicit conversion}} +auto new4 = new int[1][ambig]; // expected-error {{ambiguous conversion}} + +// [dcl.enum]p5: If the underlying type is not fixed [...] the initializing +// value [...] shall be an integral constant expression. +enum NotFixed { + enum1 = ok, + enum2 = incomplete, // expected-error {{incomplete}} + enum3 = expl, // expected-error {{explicit conversion}} + enum4 = ambig // expected-error {{ambiguous conversion}} +}; + +// [dcl.align]p2: When the alignment-specifier is of the form +// alignas(assignment-expression), the assignment-expression shall be an +// integral constant expression +int alignas(ok) alignas1; +int alignas(incomplete) alignas2; // expected-error {{incomplete}} +int alignas(expl) alignas3; // expected-error {{explicit conversion}} +int alignas(ambig) alignas4; // expected-error {{ambiguous conversion}} + +// [dcl.array]p1: If the constant-expression is present, it shall be an integral +// constant expression +// FIXME: The VLA recovery results in us giving diagnostics which aren't great +// here. +int array1[ok]; +int array2[incomplete]; // expected-error {{non-integer type}} +int array3[expl]; // expected-error {{non-integer type}} +int array4[ambig]; // expected-error {{non-integer type}} + +// [class.bit]p1: The constasnt-expression shall be an integral constant +// expression +struct Bitfields { + int bitfield1 : ok; + int bitfield2 : incomplete; // expected-error {{incomplete}} + int bitfield3 : expl; // expected-error {{explicit conversion}} + int bitfield4 : ambig; // expected-error {{ambiguous conversion}} +}; diff --git a/clang/test/CXX/expr/expr.mptr.oper/p5.cpp b/clang/test/CXX/expr/expr.mptr.oper/p5.cpp new file mode 100644 index 0000000..7380b5d --- /dev/null +++ b/clang/test/CXX/expr/expr.mptr.oper/p5.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct X0 { + void f0(); + void f1() const; + void f2() volatile; + void f3() const volatile; +}; + +void test_object_cvquals(void (X0::*pm)(), + void (X0::*pmc)() const, + void (X0::*pmv)() volatile, + void (X0::*pmcv)() const volatile, + X0 *p, + const X0 *pc, + volatile X0 *pv, + const volatile X0 *pcv, + X0 &o, + const X0 &oc, + volatile X0 &ov, + const volatile X0 &ocv) { + (p->*pm)(); + (p->*pmc)(); + (p->*pmv)(); + (p->*pmcv)(); + + (pc->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}} + (pc->*pmc)(); + (pc->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (pc->*pmcv)(); + + (pv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}} + (pv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} + (pv->*pmv)(); + (pv->*pmcv)(); + + (pcv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}} + (pcv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} + (pcv->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (pcv->*pmcv)(); + + (o.*pm)(); + (o.*pmc)(); + (o.*pmv)(); + (o.*pmcv)(); + + (oc.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}} + (oc.*pmc)(); + (oc.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (oc.*pmcv)(); + + (ov.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}} + (ov.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} + (ov.*pmv)(); + (ov.*pmcv)(); + + (ocv.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}} + (ocv.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} + (ocv.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (ocv.*pmcv)(); +} diff --git a/clang/test/CXX/expr/expr.mptr.oper/p6-0x.cpp b/clang/test/CXX/expr/expr.mptr.oper/p6-0x.cpp new file mode 100644 index 0000000..917b2da --- /dev/null +++ b/clang/test/CXX/expr/expr.mptr.oper/p6-0x.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct X { }; + +template T& lvalue(); +template T&& xvalue(); +template T prvalue(); + +// In a .* expression whose object expression is an rvalue, the +// program is ill-formed if the second operand is a pointer to member +// function with ref-qualifier &. In a ->* expression or in a .* +// expression whose object expression is an lvalue, the program is +// ill-formed if the second operand is a pointer to member function +// with ref-qualifier &&. +void test(X *xp, int (X::*pmf)(int), int (X::*l_pmf)(int) &, + int (X::*r_pmf)(int) &&) { + // No ref-qualifier. + (lvalue().*pmf)(17); + (xvalue().*pmf)(17); + (prvalue().*pmf)(17); + (xp->*pmf)(17); + + // Lvalue ref-qualifier. + (lvalue().*l_pmf)(17); + (xvalue().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}} + (prvalue().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}} + (xp->*l_pmf)(17); + + // Rvalue ref-qualifier. + (lvalue().*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}} + (xvalue().*r_pmf)(17); + (prvalue().*r_pmf)(17); + (xp->*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}} +} diff --git a/clang/test/CXX/expr/expr.post/expr.call/p7-0x.cpp b/clang/test/CXX/expr/expr.post/expr.call/p7-0x.cpp new file mode 100644 index 0000000..d51ba09 --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.call/p7-0x.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct X1 { + X1(); +}; + +struct X2 { + X2(); + ~X2(); +}; + +void vararg(...); + +void f(X1 x1, X2 x2) { + vararg(x1); // okay + vararg(x2); // expected-error{{cannot pass object of non-trivial type 'X2' through variadic function; call will abort at runtime}} +} + + +namespace PR11131 { + struct S; + + S &getS(); + + void f(...); + + void g() { + (void)sizeof(f(getS())); + } +} diff --git a/clang/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp b/clang/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp new file mode 100644 index 0000000..6ba8d51 --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// The result of the expression const_cast(v) is of type T. If T is +// an lvalue reference to object type, the result is an lvalue; if T +// is an rvalue reference to object type, the result is an xvalue;. + +unsigned int f(int); + +template T& lvalue(); +template T&& xvalue(); +template T prvalue(); + +void test_classification(const int *ptr) { + int *ptr0 = const_cast(ptr); + int *ptr1 = const_cast(xvalue()); + int *ptr2 = const_cast(prvalue()); +} diff --git a/clang/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp b/clang/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp new file mode 100644 index 0000000..cddd5cf --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct X { virtual ~X(); }; +struct Y : public X { }; +struct Z; // expected-note{{forward declaration of 'Z'}} + +void test(X &x, Y &y, Z &z) { + // If T is an rvalue reference type, v shall be an expression having + // a complete class type, and the result is an xvalue of the type + // referred to by T. + Y &&yr0 = dynamic_cast(x); + Y &&yr1 = dynamic_cast(static_cast(x)); + Y &&yr2 = dynamic_cast(z); // expected-error{{'Z' is an incomplete type}} +} diff --git a/clang/test/CXX/expr/expr.post/expr.ref/p3.cpp b/clang/test/CXX/expr/expr.post/expr.ref/p3.cpp new file mode 100644 index 0000000..98771d3 --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.ref/p3.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +template struct Node { + int lhs; + void splay( ) + { + Node n[1]; + (void)n->lhs; + } +}; + +void f() { + Node n; + return n.splay(); +} diff --git a/clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp b/clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp new file mode 100644 index 0000000..22892a6 --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// If T is an lvalue reference type or an rvalue reference to function +// type, the result is an lvalue; if T is an rvalue reference to +// object type, the result is an xvalue; + +unsigned int f(int); + +template T&& xvalue(); +void test_classification(char *ptr) { + int (&fr0)(int) = reinterpret_cast(f); + int &&ir0 = reinterpret_cast(*ptr); + int &&ir1 = reinterpret_cast(0); + int &&ir2 = reinterpret_cast('a'); + int &&ir3 = reinterpret_cast(xvalue()); +} diff --git a/clang/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp b/clang/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp new file mode 100644 index 0000000..9ef15e6 --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to +// cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1" (8.5.3). +struct A { }; +struct B : A { }; + +template T& lvalue(); +template T&& xvalue(); + +void test(A &a, B &b) { + A &&ar0 = static_cast(a); + A &&ar1 = static_cast(b); + A &&ar2 = static_cast(lvalue()); + A &&ar3 = static_cast(lvalue()); + A &&ar4 = static_cast(xvalue()); + A &&ar5 = static_cast(xvalue()); + const A &&ar6 = static_cast(a); + const A &&ar7 = static_cast(b); + const A &&ar8 = static_cast(lvalue()); + const A &&ar9 = static_cast(lvalue()); + const A &&ar10 = static_cast(xvalue()); + const A &&ar11 = static_cast(xvalue()); +} diff --git a/clang/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp b/clang/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp new file mode 100644 index 0000000..731c508 --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +enum class EC { ec1 }; + +void test0(EC ec) { + (void)static_cast(ec); + (void)static_cast(EC::ec1); + (void)static_cast(ec); + (void)static_cast(EC::ec1); + (void)static_cast(ec); + (void)static_cast(EC::ec1); + (void)static_cast(ec); + (void)static_cast(EC::ec1); + (void)static_cast(ec); + (void)static_cast(EC::ec1); + (void)static_cast(ec); + (void)static_cast(EC::ec1); +} + +namespace PR9107 { + enum E {}; + template inline _Tp* addressof(_Tp& __x) { + return (_Tp*)&(char&)__x; + } + void test() { + E a; + addressof(a); + } +} diff --git a/clang/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp b/clang/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp new file mode 100644 index 0000000..253744e --- /dev/null +++ b/clang/test/CXX/expr/expr.post/expr.type.conv/p1-0x.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct foo { + foo(); + foo(int); +}; + +int func(foo& f) { + decltype(foo())(); + f = (decltype(foo()))5; + return decltype(3)(5); +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp new file mode 100644 index 0000000..249c976 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct S { + int *j = &nonexistent; // expected-error {{use of undeclared identifier 'nonexistent'}} + int *m = &n; // ok + + int n = f(); // ok + int f(); +}; + +int i = sizeof(S::m); // ok +int j = sizeof(S::m + 42); // ok + + +struct T { + int n; + static void f() { + int a[n]; // expected-error {{invalid use of member 'n' in static member function}} + int b[sizeof n]; // ok + } +}; + +// Make sure the rule for unevaluated operands works correctly with typeid. +namespace std { + class type_info; +} +class Poly { virtual ~Poly(); }; +const std::type_info& k = typeid(S::m); +const std::type_info& m = typeid(*(Poly*)S::m); // expected-error {{invalid use of non-static data member}} +const std::type_info& n = typeid(*(Poly*)(0*sizeof S::m)); + +namespace PR11956 { + struct X { char a; }; + struct Y { int f() { return sizeof(X::a); } }; // ok + + struct A { enum E {} E; }; + struct B { int f() { return sizeof(A::E); } }; // ok +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp new file mode 100644 index 0000000..030c90c --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p3-0x.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +struct A { + int &f(int*); + float &f(int*) const noexcept; + + int *ptr; + auto g1() noexcept(noexcept(f(ptr))) -> decltype(f(this->ptr)); + auto g2() const noexcept(noexcept(f((*this).ptr))) -> decltype(f(ptr)); +}; + +void testA(A &a) { + int &ir = a.g1(); + float &fr = a.g2(); + static_assert(!noexcept(a.g1()), "exception-specification failure"); + static_assert(noexcept(a.g2()), "exception-specification failure"); +} + +struct B { + char g(); + template auto f(T t) -> decltype(t + g()) + { return t + g(); } +}; + +template auto B::f(int t) -> decltype(t + g()); + +template +struct C { + int &f(T*); + float &f(T*) const noexcept; + + T* ptr; + auto g1() noexcept(noexcept(f(ptr))) -> decltype(f((*this).ptr)); + auto g2() const noexcept(noexcept(f(((this))->ptr))) -> decltype(f(ptr)); +}; + +void test_C(C ci) { + int *p = 0; + int &ir = ci.g1(); + float &fr = ci.g2(); + static_assert(!noexcept(ci.g1()), "exception-specification failure"); + static_assert(noexcept(ci.g2()), "exception-specification failure"); +} + +namespace PR10036 { + template + void + iter_swap(I x, I y) noexcept; + + template + class A + { + T t_; + public: + void swap(A& a) noexcept(noexcept(iter_swap(&t_, &a.t_))); + }; + + void test() { + A i, j; + i.swap(j); + } +} + +namespace Static { + struct X1 { + int m; + static auto f() -> decltype(m); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} + static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}} + + static int h(); + + static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}} + }; + + auto X1::h() -> decltype(m) { return 0; } // expected-error{{'this' cannot be implicitly used in a static member function declaration}} + + template + struct X2 { + int m; + + T f(T*); + static T f(int); + + auto g(T x) -> decltype(f(x)) { return 0; } + }; + + void test_X2() { + X2().g(0); + } +} + +namespace PR12564 { + struct Base { + void bar(Base&) {} // unexpected-note {{here}} + }; + + struct Derived : Base { + // FIXME: This should be accepted. + void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // unexpected-error {{cannot bind to a value of unrelated type}} + }; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp new file mode 100644 index 0000000..4e57b74 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct S { + S *p = this; // ok + decltype(this) q; // expected-error {{invalid use of 'this' outside of a non-static member function}} + + int arr[sizeof(this)]; // expected-error {{invalid use of 'this' outside of a non-static member function}} + int sz = sizeof(this); // ok +}; + +namespace CaptureThis { + struct X { + int n = 10; + int m = [&]{return n + 1; }(); + int o = [&]{return this->m + 1; }(); + int p = [&]{return [&](int x) { return this->m + x;}(o); }(); + }; + + X x; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp new file mode 100644 index 0000000..5b3a004 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct global { +}; + +namespace PR10127 { + struct outer { + struct middle { + struct inner { + int func(); + int i; + }; + struct inner2 { + }; + struct inner3 { + }; + int mfunc(); + }; + typedef int td_int; + }; + + struct str { + operator decltype(outer::middle::inner()) (); + operator decltype(outer::middle())::inner2 (); + operator decltype(outer())::middle::inner3 (); + str(int (decltype(outer::middle::inner())::*n)(), + int (decltype(outer::middle())::inner::*o)(), + int (decltype(outer())::middle::inner::*p)()); + }; + + decltype(outer::middle::inner()) a; + void scope() { + a.decltype(outer::middle())::mfunc(); // expected-error{{'PR10127::outer::middle::mfunc' is not a member of class 'decltype(outer::middle::inner())'}} + a.decltype(outer::middle::inner())::func(); + a.decltype(outer::middle())::inner::func(); + a.decltype(outer())::middle::inner::func(); + + a.decltype(outer())::middle::inner::~inner(); + + decltype(outer())::middle::inner().func(); + } + decltype(outer::middle())::inner b; + decltype(outer())::middle::inner c; + decltype(outer())::fail d; // expected-error{{no type named 'fail' in 'PR10127::outer'}} + decltype(outer())::fail::inner e; // expected-error{{no member named 'fail' in 'PR10127::outer'}} + decltype()::fail f; // expected-error{{expected expression}} + decltype()::middle::fail g; // expected-error{{expected expression}} + + decltype(int()) h; + decltype(int())::PR10127::outer i; // expected-error{{'decltype(int())' (aka 'int') is not a class, namespace, or scoped enumeration}} + decltype(int())::global j; // expected-error{{'decltype(int())' (aka 'int') is not a class, namespace, or scoped enumeration}} + + outer::middle k = decltype(outer())::middle(); + outer::middle::inner l = decltype(outer())::middle::inner(); + + template + struct templ { + typename decltype(T())::middle::inner x; // expected-error{{type 'decltype(int())' (aka 'int') cannot be used prior to '::' because it has no members}} + }; + + template class templ; // expected-note{{in instantiation of template class 'PR10127::templ' requested here}} + template class templ; + + enum class foo { + bar, + baz + }; + + foo m = decltype(foo::bar)::baz; + + enum E { + }; + struct bar { + enum E : decltype(outer())::td_int(4); + enum F : decltype(outer())::td_int; + enum G : decltype; // expected-error{{expected '(' after 'decltype'}} + }; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm new file mode 100644 index 0000000..0c3fdb2 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks %s -verify + +void block_capture_errors() { + __block int var; // expected-note 2{{'var' declared here}} + (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} + + (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} +} + +void conversion_to_block(int captured) { + int (^b1)(int) = [=](int x) { return x + captured; }; + + const auto lambda = [=](int x) { return x + captured; }; + int (^b2)(int) = lambda; +} + +template +class ConstCopyConstructorBoom { +public: + ConstCopyConstructorBoom(ConstCopyConstructorBoom&); + + ConstCopyConstructorBoom(const ConstCopyConstructorBoom&) { + T *ptr = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}} + } + + void foo() const; +}; + +void conversion_to_block_init(ConstCopyConstructorBoom boom, + ConstCopyConstructorBoom boom2) { + const auto& lambda1([=] { boom.foo(); }); // okay + + const auto& lambda2([=] { boom2.foo(); }); // expected-note{{in instantiation of member function}} + void (^block)(void) = lambda2; +} + + +void nesting() { + int array[7]; // expected-note 2{{'array' declared here}} + [=] () mutable { + [&] { + ^ { + int i = array[2]; + i += array[3]; + }(); + }(); + }(); + + [&] { + [=] () mutable { + ^ { + int i = array[2]; // expected-error{{cannot refer to declaration with an array type inside block}} + i += array[3]; // expected-error{{cannot refer to declaration with an array type inside block}} + }(); + }(); + }(); +} + +namespace overloading { + void bool_conversion() { + if ([](){}) { + } + + bool b = []{}; + b = (bool)[]{}; + } + + void conversions() { + int (*fp)(int) = [](int x) { return x + 1; }; + fp = [](int x) { return x + 1; }; + + typedef int (*func_ptr)(int); + fp = (func_ptr)[](int x) { return x + 1; }; + + int (^bp)(int) = [](int x) { return x + 1; }; + bp = [](int x) { return x + 1; }; + + typedef int (^block_ptr)(int); + bp = (block_ptr)[](int x) { return x + 1; }; + } + + int &accept_lambda_conv(int (*fp)(int)); + float &accept_lambda_conv(int (^bp)(int)); + + void call_with_lambda() { + int &ir = accept_lambda_conv([](int x) { return x + 1; }); + } +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp new file mode 100644 index 0000000..5dac886 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -Wno-lambda-extensions -verify + +void defargs() { + auto l1 = [](int i, int j = 17, int k = 18) { return i + j + k; }; + int i1 = l1(1); + int i2 = l1(1, 2); + int i3 = l1(1, 2, 3); +} + + +void defargs_errors() { + auto l1 = [](int i, + int j = 17, + int k) { }; // expected-error{{missing default argument on parameter 'k'}} + + auto l2 = [](int i, int j = i) {}; // expected-error{{default argument references parameter 'i'}} + + int foo; + auto l3 = [](int i = foo) {}; // expected-error{{default argument references local variable 'foo' of enclosing function}} +} + +struct NonPOD { + NonPOD(); + NonPOD(const NonPOD&); + ~NonPOD(); +}; + +struct NoDefaultCtor { + NoDefaultCtor(const NoDefaultCtor&); // expected-note{{candidate constructor}} + ~NoDefaultCtor(); +}; + +template +void defargs_in_template_unused(T t) { + auto l1 = [](const T& value = T()) { }; + l1(t); +} + +template void defargs_in_template_unused(NonPOD); +template void defargs_in_template_unused(NoDefaultCtor); + +template +void defargs_in_template_used() { + auto l1 = [](const T& value = T()) { }; // expected-error{{no matching constructor for initialization of 'NoDefaultCtor'}} + l1(); // expected-note{{in instantiation of default function argument expression for 'operator()' required here}} +} + +template void defargs_in_template_used(); +template void defargs_in_template_used(); // expected-note{{in instantiation of function template specialization}} + diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp new file mode 100644 index 0000000..245e270 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +int GlobalVar; // expected-note {{declared here}} + +namespace N { + int AmbiguousVar; // expected-note {{candidate}} +} +int AmbiguousVar; // expected-note {{candidate}} +using namespace N; + +class X0 { + int Member; + + static void Overload(int); + void Overload(); + virtual X0& Overload(float); + + void explicit_capture() { + int variable; // expected-note {{declared here}} + (void)[&Overload] () {}; // expected-error {{does not name a variable}} + (void)[&GlobalVar] () {}; // expected-error {{does not have automatic storage duration}} + (void)[&AmbiguousVar] () {}; // expected-error {{reference to 'AmbiguousVar' is ambiguous}} + (void)[&Variable] () {}; // expected-error {{use of undeclared identifier 'Variable'; did you mean 'variable'}} + } +}; + +void test_reaching_scope() { + int local; // expected-note{{declared here}} + static int local_static; // expected-note{{'local_static' declared here}} + (void)[=]() { + struct InnerLocal { + void member() { + (void)[local, // expected-error{{reference to local variable 'local' declared in enclosing function 'test_reaching_scope'}} + local_static]() { // expected-error{{'local_static' cannot be captured because it does not have automatic storage duration}} + return 0; + }; + } + }; + }; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11.cpp new file mode 100644 index 0000000..d265dd7 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +void test_reaching_scope() { + int local; // expected-note{{declared here}} + static int local_static; + (void)[=]() { + struct InnerLocal { + void member() { + (void)[=]() { + return local + // expected-error{{reference to local variable 'local' declared in enclosing function 'test_reaching_scope'}} + local_static; + }; + } + }; + }; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp new file mode 100644 index 0000000..4a2a4f3 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + +void odr_used() { + int i = 17; + [i]{}(); +} + +struct ReachingThis { + static void static_foo() { + (void)[this](){}; // expected-error{{'this' cannot be captured in this context}} + + struct Local { + int i; + + void bar() { + (void)[this](){}; + (void)[&](){i = 7; }; + } + }; + } + + void foo() { + (void)[this](){}; + + struct Local { + int i; + + static void static_bar() { + (void)[this](){}; // expected-error{{'this' cannot be captured in this context}} + (void)[&](){i = 7; }; // expected-error{{invalid use of member 'i' in static member function}} + } + }; + } +}; + +void immediately_enclosing(int i) { // expected-note{{'i' declared here}} + [i]() { + [i] {}(); + }(); + + [=]() { + [i] {}(); + }(); + + []() { // expected-note{{lambda expression begins here}} + [i] {}(); // expected-error{{variable 'i' cannot be implicitly captured in a lambda with no capture-default specified}} + }(); +} + +void f1(int i) { // expected-note{{declared here}} + int const N = 20; + auto m1 = [=]{ + int const M = 30; + auto m2 = [i]{ + int x[N][M]; + x[0][0] = i; + }; + (void)N; + (void)M; + (void)m2; + }; + struct s1 { + int f; + void work(int n) { // expected-note{{declared here}} + int m = n*n; + int j = 40; // expected-note{{declared here}} + auto m3 = [this,m] { // expected-note 3{{lambda expression begins here}} + auto m4 = [&,j] { // expected-error{{variable 'j' cannot be implicitly captured in a lambda with no capture-default specified}} + int x = n; // expected-error{{variable 'n' cannot be implicitly captured in a lambda with no capture-default specified}} + x += m; + x += i; // expected-error{{variable 'i' cannot be implicitly captured in a lambda with no capture-default specified}} + x += f; + }; + }; + } + }; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp new file mode 100644 index 0000000..8bb707e --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + +void f2() { + int i = 1; + void g1(int = ([i]{ return i; })()); // expected-error{{lambda expression in default argument cannot capture any entity}} + void g2(int = ([i]{ return 0; })()); // expected-error{{lambda expression in default argument cannot capture any entity}} + void g3(int = ([=]{ return i; })()); // expected-error{{lambda expression in default argument cannot capture any entity}} + void g4(int = ([=]{ return 0; })()); + void g5(int = ([]{ return sizeof i; })()); +} + +namespace lambda_in_default_args { + int f(int = [] () -> int { int n; return ++n; } ()); + template T g(T = [] () -> T { T n; return ++n; } ()); + int k = f() + g(); +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp new file mode 100644 index 0000000..678fa4b --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +template void capture(const T&); + +class NonCopyable { + NonCopyable(const NonCopyable&); // expected-note 2 {{implicitly declared private here}} +public: + void foo() const; +}; + +class NonConstCopy { +public: + NonConstCopy(NonConstCopy&); // expected-note{{would lose const}} +}; + +void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) { + (void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}} + (void)[=] { + ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}} + }(); + + [nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}} +} + +struct NonTrivial { + NonTrivial(); + NonTrivial(const NonTrivial &); + ~NonTrivial(); +}; + +struct CopyCtorDefault { + CopyCtorDefault(); + CopyCtorDefault(const CopyCtorDefault&, NonTrivial nt = NonTrivial()); + + void foo() const; +}; + +void capture_with_default_args(CopyCtorDefault cct) { + (void)[=] () -> void { cct.foo(); }; +} + +struct ExpectedArrayLayout { + CopyCtorDefault array[3]; +}; + +void capture_array() { + CopyCtorDefault array[3]; + auto x = [=]() -> void { + capture(array[0]); + }; + static_assert(sizeof(x) == sizeof(ExpectedArrayLayout), "layout mismatch"); +} + +// Check for the expected non-static data members. + +struct ExpectedLayout { + char a; + short b; +}; + +void test_layout(char a, short b) { + auto x = [=] () -> void { + capture(a); + capture(b); + }; + static_assert(sizeof(x) == sizeof(ExpectedLayout), "Layout mismatch!"); +} + +struct ExpectedThisLayout { + ExpectedThisLayout* a; + void f() { + auto x = [this]() -> void {}; + static_assert(sizeof(x) == sizeof(ExpectedThisLayout), "Layout mismatch!"); + } +}; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp new file mode 100644 index 0000000..c4deba9 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +class NonCopyable { + NonCopyable(const NonCopyable&); +}; + +void capture_by_ref(NonCopyable nc, NonCopyable &ncr) { + int array[3]; + (void)[&nc] () -> void {}; + (void)[&ncr] () -> void {}; + (void)[&array] () -> void {}; +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp new file mode 100644 index 0000000..0cf01ad --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + + +struct X { + X(const X&) = delete; // expected-note 2{{explicitly marked deleted}} + X(X&); +}; + +void test_capture(X x) { + [x] { }(); // okay: non-const copy ctor + + [x] { + [x] { // expected-error{{call to deleted constructor of 'X'}} + }(); + }(); + + [x] { + [&x] { + [x] { // expected-error{{call to deleted constructor of 'const X'}} + }(); + }(); + }(); + + int a; + [=]{ + [&] { + int &x = a; // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}} + int &x2 = a; // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}} + }(); + }(); + + [=]{ + [&a] { + [&] { + int &x = a; // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}} + int &x2 = a; // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}} + }(); + }(); + }(); +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp new file mode 100644 index 0000000..930a4b3 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +void f3() { + float x, &r = x; + int i; + int &ir = i; + const int &irc = i; + + [=,&irc,&ir] { + static_assert(is_same::value, + "should be const float&"); + static_assert(is_same::value, "should be float"); + static_assert(is_same::value, + "should be const float&"); + static_assert(is_same::value, "should be float&"); + static_assert(is_same::value, "should be int&"); + static_assert(is_same::value, "should be int&"); + static_assert(is_same::value, + "should be const int&"); + static_assert(is_same::value, + "should be const int&"); + }(); + + [=] { + [=] () mutable { + static_assert(is_same::value, "should be float"); + static_assert(is_same::value, + "should be float&"); + }(); + }(); + + [&i] { + static_assert(is_same::value, "should be int&"); + }(); +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp new file mode 100644 index 0000000..6fe3b25 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + +struct MoveOnly { + MoveOnly(MoveOnly&&); + MoveOnly(const MoveOnly&); +}; + +template T &&move(T&); +void test_special_member_functions(MoveOnly mo, int i) { + auto lambda1 = [i]() { }; // expected-note 2 {{lambda expression begins here}} + + // Default constructor + decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka 'void { }; + auto& y = []()->void { }; // expected-error{{cannot bind to a temporary of type}} +} + +namespace std { + class type_info; +} + +struct P { + virtual ~P(); +}; + +void unevaluated_operand(P &p, int i) { + int i2 = sizeof([]()->void{}()); // expected-error{{lambda expression in an unevaluated operand}} + const std::type_info &ti1 = typeid([&]() -> P& { return p; }()); + const std::type_info &ti2 = typeid([&]() -> int { return i; }()); // expected-error{{lambda expression in an unevaluated operand}} +} + +template +struct Boom { + Boom(const Boom&) { + T* x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \ + // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}} \ + // expected-error{{cannot initialize a variable of type 'double *' with an rvalue of type 'int'}} + } + void tickle() const; +}; + +void odr_used(P &p, Boom boom_int, Boom boom_float, + Boom boom_double) { + const std::type_info &ti1 + = typeid([=,&p]() -> P& { boom_int.tickle(); return p; }()); // expected-note{{in instantiation of member function 'Boom::Boom' requested here}} + const std::type_info &ti2 + = typeid([=]() -> int { boom_float.tickle(); return 0; }()); // expected-error{{lambda expression in an unevaluated operand}} \ + // expected-note{{in instantiation of member function 'Boom::Boom' requested here}} + + auto foo = [=]() -> int { boom_double.tickle(); return 0; }; // expected-note{{in instantiation of member function 'Boom::Boom' requested here}} +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p20.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p20.cpp new file mode 100644 index 0000000..4487cfc --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p20.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + +template +void destroy(T* ptr) { + ptr->~T(); + (*ptr).~T(); +} + +void destructor() { + auto lambda = []{}; + destroy(&lambda); +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp new file mode 100644 index 0000000..7139058 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +struct DirectInitOnly { + explicit DirectInitOnly(DirectInitOnly&); +}; + +void direct_init_capture(DirectInitOnly &dio) { + [dio] {}(); +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp new file mode 100644 index 0000000..174db25 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +void print(); + +template +void print(T first, Ts... rest) { + (void)first; + print(rest...); +} + +template +void unsupported(Ts ...values) { + auto unsup = [values] {}; // expected-error{{unexpanded function parameter pack capture is unsupported}} +} + +template +void implicit_capture(Ts ...values) { + auto implicit = [&] { print(values...); }; + implicit(); +} + +template +void do_print(Ts... values) { + auto bycopy = [values...]() { print(values...); }; + bycopy(); + auto byref = [&values...]() { print(values...); }; + byref(); + + auto bycopy2 = [=]() { print(values...); }; + bycopy2(); + auto byref2 = [&]() { print(values...); }; + byref2(); +} + +template void do_print(int, float, double); + +template +void bogus_expansions(T x) { + auto l1 = [x...] {}; // expected-error{{pack expansion does not contain any unexpanded parameter packs}} + auto l2 = [Values...] {}; // expected-error{{'Values' in capture list does not name a variable}} +} + +void g(int*, float*, double*); + +template +void std_example(Args... args) { + auto lm = [&, args...] { return g(args...); }; +}; + +template void std_example(int*, float*, double*); + +template +void variadic_lambda(Args... args) { + auto lambda = [](Args... inner_args) { return g(inner_args...); }; + lambda(args...); +} + +template void variadic_lambda(int*, float*, double*); diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp new file mode 100644 index 0000000..562f92a --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +void test_nonaggregate(int i) { + auto lambda = [i]() -> void {}; // expected-note 3{{candidate constructor}} + decltype(lambda) foo = { 1 }; // expected-error{{no matching constructor}} +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp new file mode 100644 index 0000000..d816e17 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +void missing_lambda_declarator() { + [](){}(); +} + +template T get(); + +void infer_void_return_type(int i) { + if (i > 17) + return []() { }(); + + if (i > 11) + return []() { return; }(); + + return [](int x) { + switch (x) { + case 0: return get(); + case 1: return; + case 2: return { 1, 2.0 }; // expected-error{{cannot deduce lambda return type from initializer list}} + } + }(7); +} + +struct X { }; + +X infer_X_return_type(X x) { + return [&x](int y) { // expected-warning{{omitted result type}} + if (y > 0) + return X(); + else + return x; + }(5); +} + +X infer_X_return_type_fail(X x) { + return [x](int y) { // expected-warning{{omitted result type}} + if (y > 0) + return X(); + else + return x; // expected-error{{return type 'const X' must match previous return type 'X' when lambda expression has unspecified explicit return type}} + }(5); +} + +struct Incomplete; // expected-note{{forward declaration of 'Incomplete'}} +void test_result_type(int N) { + auto l1 = [] () -> Incomplete { }; // expected-error{{incomplete result type 'Incomplete' in lambda expression}} + + typedef int vla[N]; + auto l2 = [] () -> vla { }; // expected-error{{function cannot return array type 'vla' (aka 'int [N]')}} +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm new file mode 100644 index 0000000..0126e23 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +@interface A +@end + +void test_result_type() { + auto l1 = [] () -> A { }; // expected-error{{non-pointer Objective-C class type 'A' in lambda expression result}} +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp new file mode 100644 index 0000000..68460f0 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -std=c++11 %s -Winvalid-noreturn -verify + +// An attribute-specifier-seq in a lambda-declarator appertains to the +// type of the corresponding function call operator. +void test_attributes() { + auto nrl = [](int x) -> int { if (x > 0) return x; }; // expected-warning{{control may reach end of non-void lambda}} + + auto nrl2 = []() [[noreturn]] { return; }; // expected-error{{lambda declared 'noreturn' should not return}} +} + +template +struct bogus_override_if_virtual : public T { + bogus_override_if_virtual() : T(*(T*)0) { } + int operator()() const; +}; + +void test_quals() { + // This function call operator is declared const (9.3.1) if and only + // if the lambda- expression's parameter-declaration-clause is not + // followed by mutable. + auto l = [=](){}; // expected-note{{method is not marked volatile}} + const decltype(l) lc = l; + l(); + lc(); + + auto ml = [=]() mutable{}; // expected-note{{method is not marked const}} \ + // expected-note{{method is not marked volatile}} + const decltype(ml) mlc = ml; + ml(); + mlc(); // expected-error{{no matching function for call to object of type}} + + // It is neither virtual nor declared volatile. + volatile decltype(l) lv = l; + volatile decltype(ml) mlv = ml; + lv(); // expected-error{{no matching function for call to object of type}} + mlv(); // expected-error{{no matching function for call to object of type}} + + bogus_override_if_virtual bogus; +} + +// Default arguments (8.3.6) shall not be specified in the +// parameter-declaration-clause of a lambda- declarator. +// Note: Removed by core issue 974. +int test_default_args() { + return [](int i = 5, // expected-warning{{C++11 forbids default arguments for lambda expressions}} + int j = 17) { return i+j;}(5, 6); +} + +// Any exception-specification specified on a lambda-expression +// applies to the corresponding function call operator. +void test_exception_spec() { + auto tl1 = []() throw(int) {}; + auto tl2 = []() {}; + static_assert(!noexcept(tl1()), "lambda can throw"); + static_assert(!noexcept(tl2()), "lambda can throw"); + + auto ntl1 = []() throw() {}; + auto ntl2 = []() noexcept(true) {}; + auto ntl3 = []() noexcept {}; + static_assert(noexcept(ntl1()), "lambda cannot throw"); + static_assert(noexcept(ntl2()), "lambda cannot throw"); + static_assert(noexcept(ntl3()), "lambda cannot throw"); +} + diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp new file mode 100644 index 0000000..8b43cef --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +void test_conversion() { + int (*fp1)(int) = [](int x) { return x + 1; }; + void (*fp2)(int) = [](int x) { }; + + const auto lambda = [](int x) { }; + void (*fp3)(int) = lambda; + + volatile const auto lambda2 = [](int x) { }; // expected-note{{but method is not marked volatile}} + void (*fp4)(int) = lambda2; // expected-error{{no viable conversion}} +} + +void test_no_conversion() { + int (*fp1)(int) = [=](int x) { return x + 1; }; // expected-error{{no viable conversion}} + void (*fp2)(int) = [&](int x) { }; // expected-error{{no viable conversion}} +} + +void test_wonky() { + const auto l = [](int x) mutable -> int { return + 1; }; + l(17); // okay: uses conversion function +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp new file mode 100644 index 0000000..9dbe2e1 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify + +// Check that analysis-based warnings work in lambda bodies. +void analysis_based_warnings() { + (void)[]() -> int { }; // expected-warning{{control reaches end of non-void lambda}} +} + +// Check that we get the right types of captured variables (the +// semantic-analysis part of p7). +int &check_const_int(int&); +float &check_const_int(const int&); + +void test_capture_constness(int i, const int ic) { + (void)[i,ic] ()->void { + float &fr1 = check_const_int(i); + float &fr2 = check_const_int(ic); + }; + + (void)[=] ()->void { + float &fr1 = check_const_int(i); + float &fr2 = check_const_int(ic); + }; + + (void)[i,ic] () mutable ->void { + int &ir = check_const_int(i); + float &fr = check_const_int(ic); + }; + + (void)[=] () mutable ->void { + int &ir = check_const_int(i); + float &fr = check_const_int(ic); + }; + + (void)[&i,&ic] ()->void { + int &ir = check_const_int(i); + float &fr = check_const_int(ic); + }; + + (void)[&] ()->void { + int &ir = check_const_int(i); + float &fr = check_const_int(ic); + }; +} + + +struct S1 { + int x, y; + S1 &operator=(int*); + int operator()(int); + void f() { + [&]()->int { + S1 &s1 = operator=(&this->x); + return operator()(this->x + y); + }(); + } +}; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp new file mode 100644 index 0000000..d1384f1 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +class X0 { + void explicit_capture() { + int foo; + + (void)[foo, foo] () {}; // expected-error {{'foo' can appear only once}} + (void)[this, this] () {}; // expected-error {{'this' can appear only once}} + (void)[=, foo] () {}; // expected-error {{'&' must precede a capture when}} + (void)[=, &foo] () {}; + (void)[=, this] () {}; // expected-error {{'this' cannot be explicitly captured}} + (void)[&, foo] () {}; + (void)[&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}} + (void)[&, this] () {}; + } +}; + +struct S2 { + void f(int i); + void g(int i); +}; + +void S2::f(int i) { + (void)[&, i]{ }; + (void)[&, &i]{ }; // expected-error{{'&' cannot precede a capture when the capture default is '&'}} + (void)[=, this]{ }; // expected-error{{'this' cannot be explicitly captured}} + (void)[=]{ this->g(i); }; + (void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}} +} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp new file mode 100644 index 0000000..49b9c66 --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp @@ -0,0 +1,149 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify + +template +void test_attributes() { + auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}} +} + +template void test_attributes(); // expected-note{{in instantiation of function}} + +template +void call_with_zero() { + [](T *ptr) -> T& { return *ptr; }(0); +} + +template void call_with_zero(); + +template +T captures(T x, T y) { + auto lambda = [=, &y] () -> T { + T i = x; + return i + y; + }; + + return lambda(); +} + +struct X { + X(const X&); +}; + +X operator+(X, X); +X operator-(X, X); + +template int captures(int, int); +template X captures(X, X); + +template +int infer_result(T x, T y) { + auto lambda = [=](bool b) { return x + y; }; + return lambda(true); // expected-error{{no viable conversion from 'X' to 'int'}} +} + +template int infer_result(int, int); +template int infer_result(X, X); // expected-note{{in instantiation of function template specialization 'infer_result' requested here}} + +// Make sure that lambda's operator() can be used from templates. +template +void accept_lambda(F f) { + f(1); +} + +template +void pass_lambda(T x) { + accept_lambda([&x](T y) { return x + y; }); +} + +template void pass_lambda(int); + +namespace std { + class type_info; +} + +namespace p2 { + struct P { + virtual ~P(); + }; + + template + struct Boom { + Boom(const Boom&) { + T* x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \ + // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}} + } + void tickle() const; + }; + + template + void odr_used(R &r, Boom boom) { + const std::type_info &ti + = typeid([=,&r] () -> R& { // expected-error{{lambda expression in an unevaluated operand}} + boom.tickle(); // expected-note{{in instantiation of member function}} + return r; + }()); + } + + template void odr_used(int&, Boom); // expected-note{{in instantiation of function template specialization}} + + template + void odr_used2(R &r, Boom boom) { + const std::type_info &ti + = typeid([=,&r] () -> R& { + boom.tickle(); // expected-note{{in instantiation of member function}} + return r; + }()); + } + + template void odr_used2(P&, Boom); +} + +namespace p5 { + struct NonConstCopy { + NonConstCopy(const NonConstCopy&) = delete; + NonConstCopy(NonConstCopy&); + }; + + template + void double_capture(T &nc) { + [=] () mutable { + [=] () mutable { + T nc2(nc); + }(); + }(); + } + + template void double_capture(NonConstCopy&); +} + +namespace NonLocalLambdaInstantation { + template + struct X { + static int value; + }; + + template + int X::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}} + + template int X::value; + template int X::value; + template int X::value; // expected-note{{in instantiation of static data member }} + + template + void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \ + // expected-note{{passing argument to parameter 'x' here}} + + void call_defaults() { + defaults(); + defaults(); + defaults(); // expected-note{{in instantiation of default function argument expression for 'defaults' required here}} + } + + template + struct X2 { + int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}} + }; + + X2 x2i; + X2 x2f; + X2 x2ip; // expected-note{{in instantiation of template class 'NonLocalLambdaInstantation::X2' requested here}} +} diff --git a/clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp b/clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp new file mode 100644 index 0000000..ecb2918 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -verify %s + +// If the object being deleted has incomplete class type at the point of +// deletion and the complete class has a non-trivial destructor or a +// deallocation function, the behavior is undefined. + +// The trivial case. +class T0; // expected-note {{forward declaration}} +void f0(T0 *a) { delete a; } // expected-warning {{deleting pointer to incomplete type}} +class T0 { ~T0(); }; + +// The trivial case, inside a template instantiation. +template +struct T1_A { T *x; ~T1_A() { delete x; } }; // expected-warning {{deleting pointer to incomplete type}} +class T1_B; // expected-note {{forward declaration}} +void f0() { T1_A x; } // expected-note {{in instantiation of member function}} + +// This case depends on when we check T2_C::f0. +class T2_A; +template +struct T2_B { void f0(T *a) { delete a; } }; +struct T2_C { T2_B x; void f0(T2_A *a) { x.f0(a); } }; +void f0(T2_A *a) { T2_C x; x.f0(a); } +class T2_A { }; + +// An alternate version of the same. +class T3_A; +template +struct T3_B { + void f0(T *a) { + delete a; // expected-error{{calling a private destructor of class 'T3_A'}} + } +}; + +struct T3_C { + T3_B x; + void f0(T3_A *a) { + x.f0(a); // expected-note{{in instantiation of member function 'T3_B::f0' requested here}} + } +}; + +void f0(T3_A *a) { T3_C x; x.f0(a); } +class T3_A { +private: + ~T3_A(); // expected-note{{declared private here}} +}; diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp new file mode 100644 index 0000000..27b915e --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm-only %s + +// this used to crash due to templ's dtor not being marked as used by the +// new expression in func() +struct non_trivial { + non_trivial() {} + ~non_trivial() {} +}; +template < typename T > class templ { + non_trivial n; +}; +void func() { + new templ[1][1]; +} diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp new file mode 100644 index 0000000..0d108eb --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class ctor { + ctor(); // expected-note{{implicitly declared private here}} +}; + +class dtor { + ~dtor(); // expected-note 3 {{implicitly declared private here}} +}; + +void test() { + new ctor[0]; // expected-error{{calling a private constructor of class 'ctor'}} + new dtor[0]; // expected-error{{calling a private destructor of class 'dtor'}} + new dtor[3]; // expected-error{{calling a private destructor of class 'dtor'}} + new dtor[3][3]; // expected-error{{calling a private destructor of class 'dtor'}} +} diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p19.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p19.cpp new file mode 100644 index 0000000..bb69fd5 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p19.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s +typedef __SIZE_TYPE__ size_t; + +// Operator delete template for placement new with global lookup +template +struct X0 { + X0(); + + static void* operator new(size_t) { + return I; // expected-error{{cannot initialize}} + } + + static void operator delete(void*) { + int *ip = I; // expected-error{{cannot initialize}} + } +}; + +void test_X0() { + // Using the global operator new suppresses the search for a + // operator delete in the class. + ::new X0<2>; + + new X0<3>; // expected-note 2{{instantiation}} +} + +// Operator delete template for placement new[] with global lookup +template +struct X1 { + X1(); + + static void* operator new[](size_t) { + return I; // expected-error{{cannot initialize}} + } + + static void operator delete[](void*) { + int *ip = I; // expected-error{{cannot initialize}} + } +}; + +void test_X1() { + // Using the global operator new suppresses the search for a + // operator delete in the class. + ::new X1<2> [17]; + + new X1<3> [17]; // expected-note 2{{instantiation}} +} diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp new file mode 100644 index 0000000..4ebbfce --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +template +struct only { + only(T); + template only(U) = delete; +}; + +void f() { + only p = new const auto (0); + only q = new (auto) (0.0); + + new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}} + new (const auto)(); // expected-error{{new expression for type 'auto const' requires a constructor argument}} + new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}} +} + +void p2example() { + only r = new auto(1); + auto x = new auto('a'); + + only testX = x; +} diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp new file mode 100644 index 0000000..eca1ec7 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fexceptions %s +typedef __SIZE_TYPE__ size_t; + +struct S { + // Placement allocation function: + static void* operator new(size_t, size_t); + // Usual (non-placement) deallocation function: + static void operator delete(void*, size_t); // expected-note{{declared here}} +}; + +void testS() { + S* p = new (0) S; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}} +} diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p20.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p20.cpp new file mode 100644 index 0000000..8cbe2b9 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.new/p20.cpp @@ -0,0 +1,141 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s +typedef __SIZE_TYPE__ size_t; + +// Overloaded operator delete with two arguments +template +struct X0 { + X0(); + static void* operator new(size_t); + static void operator delete(void*, size_t) { + int *ip = I; // expected-error{{cannot initialize}} + } +}; + +void test_X0() { + new X0<1>; // expected-note{{instantiation}} +} + +// Overloaded operator delete with one argument +template +struct X1 { + X1(); + + static void* operator new(size_t); + static void operator delete(void*) { + int *ip = I; // expected-error{{cannot initialize}} + } +}; + +void test_X1() { + new X1<1>; // expected-note{{instantiation}} +} + +// Overloaded operator delete for placement new +template +struct X2 { + X2(); + + static void* operator new(size_t, double, double); + static void* operator new(size_t, int, int); + + static void operator delete(void*, const int, int) { + int *ip = I; // expected-error{{cannot initialize}} + } + + static void operator delete(void*, double, double); +}; + +void test_X2() { + new (0, 0) X2<1>; // expected-note{{instantiation}} +} + +// Operator delete template for placement new +struct X3 { + X3(); + + static void* operator new(size_t, double, double); + + template + static void operator delete(void*, T x, T) { + double *dp = &x; + int *ip = &x; // expected-error{{cannot initialize}} + } +}; + +void test_X3() { + new (0, 0) X3; // expected-note{{instantiation}} +} + +// Operator delete template for placement new in global scope. +struct X4 { + X4(); + static void* operator new(size_t, double, double); +}; + +template +void operator delete(void*, T x, T) { + double *dp = &x; + int *ip = &x; // expected-error{{cannot initialize}} +} + +void test_X4() { + new (0, 0) X4; // expected-note{{instantiation}} +} + +// Useless operator delete hides global operator delete template. +struct X5 { + X5(); + static void* operator new(size_t, double, double); + void operator delete(void*, double*, double*); +}; + +void test_X5() { + new (0, 0) X5; // okay, we found X5::operator delete but didn't pick it +} + +// Operator delete template for placement new +template +struct X6 { + X6(); + + static void* operator new(size_t) { + return I; // expected-error{{cannot initialize}} + } + + static void operator delete(void*) { + int *ip = I; // expected-error{{cannot initialize}} + } +}; + +void test_X6() { + new X6<3>; // expected-note 2{{instantiation}} +} + +void *operator new(size_t, double, double, double); + +template +void operator delete(void*, T x, T, T) { + double *dp = &x; + int *ip = &x; // expected-error{{cannot initialize}} +} +void test_int_new() { + new (1.0, 1.0, 1.0) int; // expected-note{{instantiation}} +} + +// We don't need an operator delete if the type has a trivial +// constructor, since we know that constructor cannot throw. +// FIXME: Is this within the standard? Seems fishy, but both EDG+GCC do it. +#if 0 +template +struct X7 { + static void* operator new(size_t); + static void operator delete(void*, size_t) { + int *ip = I; // okay, since it isn't instantiated. + } +}; + +void test_X7() { + new X7<1>; +} +#endif + diff --git a/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp b/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp new file mode 100644 index 0000000..afd8ef0 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Test parsing + semantic analysis +template struct count_types { + static const unsigned value = sizeof...(Types); +}; + +template struct count_ints { + static const unsigned value = sizeof...(Values); +}; + +// Test instantiation +int check_types[count_types::value == 3? 1 : -1]; +int check_ints[count_ints<1, 2, 3, 4, 5>::value == 5? 1 : -1]; + +// Test instantiation involving function parameter packs. +struct any { + template any(T); +}; + +template +void init_me(Inits ...inits) { + any array[sizeof...(inits)] = { inits... }; +} + +template void init_me(int, float, double*); + +// Test parser and semantic recovery. +template struct count_ints_2 { + static const unsigned value = sizeof...(Value); // expected-error{{'Value' does not refer to the name of a parameter pack}} +}; + +template // expected-note{{parameter pack 'Types' declared here}} +struct count_types_2 { + static const unsigned value = sizeof... Type; // expected-error{{missing parentheses around the size of parameter pack 'Type'}} \ + // expected-error{{Type' does not refer to the name of a parameter pack; did you mean 'Types'?}} +}; + diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp new file mode 100644 index 0000000..5c1029f --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++11 -include %S/ser.h %s -o - | FileCheck %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-pch -o %t-ser.pch -std=c++11 -x c++ %S/ser.h +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++11 -include-pch %t-ser.pch %s -o - | FileCheck %s + +struct D { + ~D() throw(); +}; +struct E { + ~E() throw(); +}; + +void test() { + bool b; + // CHECK: store i8 1 + b = noexcept(0); + // CHECK: store i8 0 + b = noexcept(throw 0); + b = f1(); + b = f2(); + + // CHECK-NOT: call void @_ZN1ED1Ev + // CHECK: call void @_ZN1DD1Ev + D(), noexcept(E()); +} +// CHECK: ret i1 true +// CHECK: ret i1 false diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp new file mode 100644 index 0000000..b5de1a7 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp @@ -0,0 +1,189 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -fms-extensions %s + +#define P(e) static_assert(noexcept(e), "expected nothrow") +#define N(e) static_assert(!noexcept(e), "expected throw") +#define B(b, e) static_assert(b == noexcept(e), "expectation failed") + +void simple() { + P(0); + P(0 + 0); + int i; + P(i); + P(sizeof(0)); + P(static_cast(0)); + N(throw 0); + N((throw 0, 0)); +} + +void nospec(); +void allspec() throw(...); +void intspec() throw(int); +void emptyspec() throw(); +void nothrowattr() __attribute__((nothrow)); +void noexcept_true() noexcept; +void noexcept_false() noexcept(false); + +void call() { + N(nospec()); + N(allspec()); + N(intspec()); + P(emptyspec()); + P(nothrowattr()); + P(noexcept_true()); + N(noexcept_false()); +} + +void (*pnospec)(); +void (*pallspec)() throw(...); +void (*pintspec)() throw(int); +void (*pemptyspec)() throw(); + +void callptr() { + N(pnospec()); + N((*pnospec)()); + N(pallspec()); + N((*pallspec)()); + N(pintspec()); + N((*pintspec)()); + P(pemptyspec()); + P((*pemptyspec)()); +} + +struct S1 { + void nospec(); + void allspec() throw(...); + void intspec() throw(int); + void emptyspec() throw(); +}; + +void callmem() { + S1 s; + N(s.nospec()); + N(s.allspec()); + N(s.intspec()); + P(s.emptyspec()); +} + +void (S1::*mpnospec)(); +void (S1::*mpallspec)() throw(...); +void (S1::*mpintspec)() throw(int); +void (S1::*mpemptyspec)() throw(); + +void callmemptr() { + S1 s; + N((s.*mpnospec)()); + N((s.*mpallspec)()); + N((s.*mpintspec)()); + P((s.*mpemptyspec)()); +} + +struct S2 { + S2(); + S2(int, int) throw(); + void operator +(); + void operator -() throw(); + void operator +(int); + void operator -(int) throw(); + operator int(); + operator float() throw(); +}; + +void *operator new(__typeof__(sizeof(int)) sz, int) throw(); + +struct Bad1 { + ~Bad1() throw(int); +}; +struct Bad2 { + void operator delete(void*) throw(int); +}; + +typedef int X; + +void implicits() { + N(new int); + P(new (0) int); + P(delete (int*)0); + N(delete (Bad1*)0); + N(delete (Bad2*)0); + N(S2()); + P(S2(0, 0)); + S2 s; + N(+s); + P(-s); + N(s + 0); + P(s - 0); + N(static_cast(s)); + P(static_cast(s)); + N(Bad1()); + P(X().~X()); +} + +struct V { + virtual ~V() throw(); +}; +struct D : V {}; + +void dyncast() { + V *pv = 0; + D *pd = 0; + P(dynamic_cast(*pd)); + P(dynamic_cast(pd)); + N(dynamic_cast(*pv)); + P(dynamic_cast(pv)); +} + +namespace std { + struct type_info {}; +} + +void idtype() { + P(typeid(V)); + P(typeid((V*)0)); + P(typeid(*(S1*)0)); + N(typeid(*(V*)0)); +} + +void uneval() { + P(sizeof(typeid(*(V*)0))); + P(typeid(typeid(*(V*)0))); +} + +struct G1 {}; +struct G2 { int i; }; +struct G3 { S2 s; }; + +void gencon() { + P(G1()); + P(G2()); + N(G3()); +} + +template void f(T&&) noexcept; +template +void late() { + B(b, typeid(*(T*)0)); + B(b, T(1)); + B(b, static_cast(S2(0, 0))); + B(b, S1() + T()); + P(f(T())); + P(new (0) T); + P(delete (T*)0); +} +struct S3 { + virtual ~S3() throw(); + S3() throw(); + explicit S3(int); + S3(const S2&); +}; +template T&& f2() noexcept; +template +void late2() { + P(dynamic_cast(f2())); +} +void operator +(const S1&, float) throw(); +void operator +(const S1&, const S3&); +void tlate() { + late(); + late(); + late2(); +} diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h new file mode 100644 index 0000000..e6e7b79 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h @@ -0,0 +1,8 @@ +// Serialization testing helper for noexcept, included by cg.cpp. + +inline bool f1() { + return noexcept(0); +} +inline bool f2() { + return noexcept(throw 0); +} diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp new file mode 100644 index 0000000..2dd6b23 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify + +namespace rdar10544564 { + // Check that we don't attempt to use an overloaded operator& when + // naming a pointer-to-member. + struct X { + void** operator & (); + }; + + struct Y + { + public: + X member; + X memfunc1(); + X memfunc2(); + X memfunc2(int); + + void test() { + X Y::*data_mem_ptr = &Y::member; + X (Y::*func_mem_ptr1)() = &Y::memfunc1; + X (Y::*func_mem_ptr2)() = &Y::memfunc2; + } + }; + + X Y::*data_mem_ptr = &Y::member; + X (Y::*func_mem_ptr1)() = &Y::memfunc1; + X (Y::*func_mem_ptr2)() = &Y::memfunc2; +} diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp new file mode 100644 index 0000000..06cc610 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// rdar://problem/8347416 +namespace test0 { + struct A { + void foo(void (A::*)(int)); // expected-note {{passing argument to parameter here}} + template void g(T); + + void test() { + foo(&g); // expected-error {{can't form member pointer of type 'void (test0::A::*)(int)' without '&' and class name}} + } + }; +} + +// This should succeed. +namespace test1 { + struct A { + static void f(void (A::*)()); + static void f(void (*)(int)); + void g(); + static void g(int); + + void test() { + f(&g); + } + }; +} + +// Also rdar://problem/8347416 +namespace test2 { + struct A { + static int foo(short); + static int foo(float); + int foo(int); + int foo(double); + + void test(); + }; + + void A::test() { + int (A::*ptr)(int) = &(A::foo); // expected-error {{can't form member pointer of type 'int (test2::A::*)(int)' without '&' and class name}} + } +} diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp new file mode 100644 index 0000000..ac11940 --- /dev/null +++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// -- prvalue of arithmetic + +bool b = !0; + +bool b2 = !1.2; + +bool b3 = !4; + +// -- unscoped enumeration +enum { E, F }; + +bool b4 = !E; +bool b5 = !F; + +// -- pointer, +bool b6 = !&b4; +void f(); +bool b61 = !&f; + +// -- or pointer to member type can be converted to a prvalue of type bool. +struct S { void f() { } }; + +bool b7 = !&S::f; + + +bool b8 = !S(); //expected-error {{invalid argument type 'S'}} + +namespace PR8181 +{ + bool f() { } // expected-note{{possible target for call}} + void f(char) { } // expected-note{{possible target for call}} + bool b = !&f; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} +} diff --git a/clang/test/CXX/expr/p3.cpp b/clang/test/CXX/expr/p3.cpp new file mode 100644 index 0000000..6b243c2 --- /dev/null +++ b/clang/test/CXX/expr/p3.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +double operator +(double, double); // expected-error{{overloaded 'operator+' must have at least one parameter of class or enumeration type}} + +struct A +{ + operator int(); +}; + +int main() +{ + A a, b; + int i0 = a + 1; + int i1 = a + b; +} diff --git a/clang/test/CXX/expr/p8.cpp b/clang/test/CXX/expr/p8.cpp new file mode 100644 index 0000000..2f6c094 --- /dev/null +++ b/clang/test/CXX/expr/p8.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int a0; +const volatile int a1 = 2; +int a2[16]; +int a3(); + +void f0(int); +void f1(int *); +void f2(int (*)()); + +int main() +{ + f0(a0); + f0(a1); + f1(a2); + f2(a3); +} diff --git a/clang/test/CXX/expr/p9.cpp b/clang/test/CXX/expr/p9.cpp new file mode 100644 index 0000000..803b0cc --- /dev/null +++ b/clang/test/CXX/expr/p9.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// floating-point overloads + +__typeof__(0 + 0.0L) ld0; +long double &ldr = ld0; + +__typeof__(0 + 0.0) d0; +double &dr = d0; + +__typeof__(0 + 0.0f) f0; +float &fr = f0; + +// integral promotions + +signed char c0; +__typeof__(c0 + c0) c1; +int &cr = c1; + +unsigned char uc0; +__typeof__(uc0 + uc0) uc1; +int &ucr = uc1; + +short s0; +__typeof__(s0 + s0) s1; +int &sr = s1; + +unsigned short us0; +__typeof__(us0 + us0) us1; +int &usr = us1; + +// integral overloads + +__typeof__(0 + 0UL) ul0; +unsigned long &ulr = ul0; + +template struct selector; +template<> struct selector { typedef long type; }; +template<> struct selector {typedef unsigned long type; }; +__typeof__(0U + 0L) ui_l0; +selector<(sizeof(long) > sizeof(unsigned int))>::type &ui_lr = ui_l0; + +__typeof__(0 + 0L) l0; +long &lr = l0; + +__typeof__(0 + 0U) u0; +unsigned &ur = u0; + +__typeof__(0 + 0) i0; +int &ir = i0; diff --git a/clang/test/CXX/lex/lex.charset/p2-cxx11.cpp b/clang/test/CXX/lex/lex.charset/p2-cxx11.cpp new file mode 100644 index 0000000..b9192ce --- /dev/null +++ b/clang/test/CXX/lex/lex.charset/p2-cxx11.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +char c00 = '\u0000'; // ok +char c01 = '\u0001'; // ok +char c1f = '\u001f'; // ok +char c20 = '\u0020'; // ' ', ok +char c22 = '\u0022'; // ", ok +char c23 = '\u0023'; // #, ok +char c24 = '\u0024'; // $, ok +char c25 = '\u0025'; // %, ok +char c27 = '\u0027'; // ', ok +char c3f = '\u003f'; // ?, ok +char c40 = '\u0040'; // @, ok +char c41 = '\u0041'; // A, ok +char c5f = '\u005f'; // _, ok +char c60 = '\u0060'; // `, ok +char c7e = '\u007e'; // ~, ok +char c7f = '\u007f'; // ok + +wchar_t w007f = L'\u007f'; +wchar_t w0080 = L'\u0080'; +wchar_t w009f = L'\u009f'; +wchar_t w00a0 = L'\u00a0'; + +wchar_t wd799 = L'\ud799'; +wchar_t wd800 = L'\ud800'; // expected-error {{invalid universal character}} +wchar_t wdfff = L'\udfff'; // expected-error {{invalid universal character}} +wchar_t we000 = L'\ue000'; + +char32_t w10fffe = U'\U0010fffe'; +char32_t w10ffff = U'\U0010ffff'; +char32_t w110000 = U'\U00110000'; // expected-error {{invalid universal character}} + +const char *p1 = "\u0000\u0001\u001f\u0020\u0022\u0023\u0024\u0025\u0027\u003f\u0040\u0041\u005f\u0060\u007e\u007f"; +const wchar_t *p2 = L"\u0000\u0012\u004e\u007f\u0080\u009f\u00a0\ud799\ue000"; +const char *p3 = u8"\u0000\u0012\u004e\u007f\u0080\u009f\u00a0\ud799\ue000"; +const char16_t *p4 = u"\u0000\u0012\u004e\u007f\u0080\u009f\u00a0\ud799\ue000"; +const char32_t *p5 = U"\u0000\u0012\u004e\u007f\u0080\u009f\u00a0\ud799\ue000"; +const wchar_t *p6 = L"foo \U00110000 bar"; // expected-error {{invalid universal character}} +const char *p7 = u8"foo \U0000d800 bar"; // expected-error {{invalid universal character}} +const char16_t *p8 = u"foo \U0000dfff bar"; // expected-error {{invalid universal character}} +const char32_t *p9 = U"foo \U0010ffff bar"; // ok diff --git a/clang/test/CXX/lex/lex.charset/p2-cxx98.cpp b/clang/test/CXX/lex/lex.charset/p2-cxx98.cpp new file mode 100644 index 0000000..a5b7ab6 --- /dev/null +++ b/clang/test/CXX/lex/lex.charset/p2-cxx98.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -verify -std=c++98 %s + +char c00 = '\u0000'; // expected-error {{universal character name refers to a control character}} +char c01 = '\u0001'; // expected-error {{universal character name refers to a control character}} +char c1f = '\u001f'; // expected-error {{universal character name refers to a control character}} +char c20 = '\u0020'; // ' ', expected-error {{character ' ' cannot be specified by a universal character name}} +char c22 = '\u0022'; // ", expected-error {{character '"' cannot be specified by a universal character name}} +char c23 = '\u0023'; // #, expected-error {{character '#' cannot be specified by a universal character name}} +char c24 = '\u0024'; // $, ok +char c25 = '\u0025'; // %, expected-error {{character '%' cannot be specified by a universal character name}} +char c27 = '\u0027'; // ', expected-error {{character ''' cannot be specified by a universal character name}} +char c3f = '\u003f'; // ?, expected-error {{character '?' cannot be specified by a universal character name}} +char c40 = '\u0040'; // @, ok +char c41 = '\u0041'; // A, expected-error {{character 'A' cannot be specified by a universal character name}} +char c5f = '\u005f'; // _, expected-error {{character '_' cannot be specified by a universal character name}} +char c60 = '\u0060'; // `, ok +char c7e = '\u007e'; // ~, expected-error {{character '~' cannot be specified by a universal character name}} +char c7f = '\u007f'; // expected-error {{universal character name refers to a control character}} + +wchar_t w007f = L'\u007f'; // expected-error {{universal character name refers to a control character}} +wchar_t w0080 = L'\u0080'; // expected-error {{universal character name refers to a control character}} +wchar_t w009f = L'\u009f'; // expected-error {{universal character name refers to a control character}} +wchar_t w00a0 = L'\u00a0'; + +wchar_t wd799 = L'\ud799'; +wchar_t wd800 = L'\ud800'; // expected-error {{invalid universal character}} +wchar_t wdfff = L'\udfff'; // expected-error {{invalid universal character}} +wchar_t we000 = L'\ue000'; + +const char *s00 = "\u0000"; // expected-error {{universal character name refers to a control character}} +const char *s01 = "\u0001"; // expected-error {{universal character name refers to a control character}} +const char *s1f = "\u001f"; // expected-error {{universal character name refers to a control character}} +const char *s20 = "\u0020"; // ' ', expected-error {{character ' ' cannot be specified by a universal character name}} +const char *s22 = "\u0022"; // ", expected-error {{character '"' cannot be specified by a universal character name}} +const char *s23 = "\u0023"; // #, expected-error {{character '#' cannot be specified by a universal character name}} +const char *s24 = "\u0024"; // $, ok +const char *s25 = "\u0025"; // %, expected-error {{character '%' cannot be specified by a universal character name}} +const char *s27 = "\u0027"; // ', expected-error {{character ''' cannot be specified by a universal character name}} +const char *s3f = "\u003f"; // ?, expected-error {{character '?' cannot be specified by a universal character name}} +const char *s40 = "\u0040"; // @, ok +const char *s41 = "\u0041"; // A, expected-error {{character 'A' cannot be specified by a universal character name}} +const char *s5f = "\u005f"; // _, expected-error {{character '_' cannot be specified by a universal character name}} +const char *s60 = "\u0060"; // `, ok +const char *s7e = "\u007e"; // ~, expected-error {{character '~' cannot be specified by a universal character name}} +const char *s7f = "\u007f"; // expected-error {{universal character name refers to a control character}} + +const wchar_t *ws007f = L"\u007f"; // expected-error {{universal character name refers to a control character}} +const wchar_t *ws0080 = L"\u0080"; // expected-error {{universal character name refers to a control character}} +const wchar_t *ws009f = L"\u009f"; // expected-error {{universal character name refers to a control character}} +const wchar_t *ws00a0 = L"\u00a0"; + +const wchar_t *wsd799 = L"\ud799"; +const wchar_t *wsd800 = L"\ud800"; // expected-error {{invalid universal character}} +const wchar_t *wsdfff = L"\udfff"; // expected-error {{invalid universal character}} +const wchar_t *wse000 = L"\ue000"; diff --git a/clang/test/CXX/lex/lex.literal/lex.ccon/p1.cpp b/clang/test/CXX/lex/lex.literal/lex.ccon/p1.cpp new file mode 100644 index 0000000..5342153 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ccon/p1.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Check types of char literals +extern char a; +extern __typeof('a') a; +extern int b; +extern __typeof('asdf') b; +extern wchar_t c; +extern __typeof(L'a') c; +#if __cplusplus >= 201103L +extern char16_t d; +extern __typeof(u'a') d; +extern char32_t e; +extern __typeof(U'a') e; +#endif diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp new file mode 100644 index 0000000..1c227a1 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}} +void operator "" _p31(long double); +long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}} + +float hexfloat = 0x1p31; // allow hexfloats diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp new file mode 100644 index 0000000..1b5d388 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +using size_t = decltype(sizeof(int)); +void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}} +void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}} + +template +void f() { + // A program containing a reserved ud-suffix is ill-formed. + 123wibble; // expected-error {{invalid suffix 'wibble'}} + 123.0wibble; // expected-error {{invalid suffix 'wibble'}} + const char *p = ""wibble; // expected-error {{invalid suffix on literal; C++11 requires a space between literal and identifier}} expected-error {{expected ';'}} + const char *q = R"x("hello")x"wibble; // expected-error {{invalid suffix on literal; C++11 requires a space between literal and identifier}} expected-error {{expected ';'}} +} diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p2.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p2.cpp new file mode 100644 index 0000000..3f3f796 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p2.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +typedef decltype(sizeof(int)) size_t; + +// FIXME: These diagnostics should say 'size_t' instead of 'unsigned long' +int a = 123_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template}} +int b = 4.2_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with argument of type 'long double' or 'const char *', and no matching literal operator template}} +int c = "foo"_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with arguments of types 'const char *' and 'unsigned}} +int d = L"foo"_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with arguments of types 'const wchar_t *' and 'unsigned}} +int e = u8"foo"_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with arguments of types 'const char *' and 'unsigned}} +int f = u"foo"_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with arguments of types 'const char16_t *' and 'unsigned}} +int g = U"foo"_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with arguments of types 'const char32_t *' and 'unsigned}} +int h = 'y'_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with argument of type 'char'}} +int i = L'y'_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with argument of type 'wchar_t'}} +int j = u'y'_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with argument of type 'char16_t'}} +int k = U'y'_x; // expected-error {{no matching literal operator for call to 'operator "" _x' with argument of type 'char32_t'}} diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp new file mode 100644 index 0000000..43f3468 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +int &operator "" _x1 (unsigned long long); +int &i1 = 0x123_x1; + +double &operator "" _x1 (const char *); +int &i2 = 45_x1; + +template char &operator "" _x1 (); +int &i3 = 0377_x1; + +int &i4 = 90000000000000000000000000000000000000000000000_x1; // expected-warning {{integer constant is too large}} + +double &operator "" _x2 (const char *); +double &i5 = 123123123123123123123123123123123123123123123_x2; + +template constexpr int operator "" _x3() { return sizeof...(Cs); } +static_assert(123456789012345678901234567890123456789012345678901234567890_x3 == 60, ""); diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp new file mode 100644 index 0000000..011e832 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +int &operator "" _x1 (long double); +int &i1 = 0.123_x1; + +double &operator "" _x1 (const char *); +int &i2 = 45._x1; + +template char &operator "" _x1 (); +int &i3 = 0377e-1_x1; + +int &i4 = 1e1000000_x1; // expected-warning {{too large for type 'long double'}} + +double &operator "" _x2 (const char *); +double &i5 = 1e1000000_x2; + +template constexpr int operator "" _x3() { return sizeof...(Cs); } +static_assert(1e1000000_x3 == 9, ""); diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp new file mode 100644 index 0000000..4655aa1 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +using size_t = decltype(sizeof(int)); + +int &operator "" _x1 (const char *); +double &operator "" _x1 (const char *, size_t); +double &i1 = "foo"_x1; +double &i2 = u8"foo"_x1; +double &i3 = L"foo"_x1; // expected-error {{no matching literal operator}} + +char &operator "" _x1(const wchar_t *, size_t); +char &i4 = L"foo"_x1; // ok +double &i5 = R"(foo)"_x1; // ok diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp new file mode 100644 index 0000000..23cd708 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +using size_t = decltype(sizeof(int)); + +int &operator "" _x1 (const char *); +double &i1 = 'a'_x1; // expected-error {{no matching literal operator}} +double &operator "" _x1 (wchar_t); +double &i2 = L'a'_x1; +double &i3 = 'a'_x1; // expected-error {{no matching literal operator}} +double &i4 = operator"" _x1('a'); // ok + +char &operator "" _x1(char16_t); +char &i5 = u'a'_x1; // ok +double &i6 = L'a'_x1; // ok diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp new file mode 100644 index 0000000..79c9394 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +using size_t = decltype(sizeof(int)); +namespace std { + struct string {}; +} + +template struct same_type; +template struct same_type {}; + +namespace std_example { + +long double operator "" _w(long double); +std::string operator "" _w(const char16_t*, size_t); +unsigned operator "" _w(const char*); +int main() { + auto v1 = 1.2_w; // calls operator "" _w(1.2L) + auto v2 = u"one"_w; // calls operator "" _w(u"one", 3) + auto v3 = 12_w; // calls operator "" _w("12") + "two"_w; // expected-error {{no matching literal operator}} + + same_type test1; + same_type test2; + same_type test3; +} + +} diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp new file mode 100644 index 0000000..d907822 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +using size_t = decltype(sizeof(int)); +constexpr const char *operator "" _id(const char *p, size_t) { return p; } +constexpr const char *s = "foo"_id "bar" "baz"_id "quux"; + +constexpr bool streq(const char *p, const char *q) { + return *p == *q && (!*p || streq(p+1, q+1)); +} +static_assert(streq(s, "foobarbazquux"), ""); + +constexpr const char *operator "" _trim(const char *p, size_t n) { + return *p == ' ' ? operator "" _trim(p + 1, n - 1) : p; +} +constexpr const char *t = " " " "_trim " foo"; +static_assert(streq(t, "foo"), ""); + +const char *u = "foo" "bar"_id "baz" "quux"_di "corge"; // expected-error {{differing user-defined suffixes ('_id' and '_di') in string literal concatenation}} diff --git a/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp b/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp new file mode 100644 index 0000000..65e27b4 --- /dev/null +++ b/clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +using size_t = decltype(sizeof(int)); +void operator "" _x(const wchar_t *, size_t); + +namespace std_example { + +int main() { + L"A" "B" "C"_x; + "P"_x "Q" "R"_y; // expected-error {{differing user-defined suffixes ('_x' and '_y') in string literal concatenation}} +} + +} diff --git a/clang/test/CXX/lex/lex.pptoken/p3-0x.cpp b/clang/test/CXX/lex/lex.pptoken/p3-0x.cpp new file mode 100644 index 0000000..3d56ac1 --- /dev/null +++ b/clang/test/CXX/lex/lex.pptoken/p3-0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +int a<::> = { 1, 2, 3 }; +int b = a<:::a<:0:>:>; +bool c = a<:0:><::b; + +template void f() {} +template void f<::b>(); + +#define x a<:: ## : b :> +int d = x; // expected-error {{pasting formed ':::', an invalid preprocessing token}} expected-error {{expected unqualified-id}} diff --git a/clang/test/CXX/lex/lex.trigraph/p1.cpp b/clang/test/CXX/lex/lex.trigraph/p1.cpp new file mode 100644 index 0000000..aacbc55 --- /dev/null +++ b/clang/test/CXX/lex/lex.trigraph/p1.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -trigraphs -Wtrigraphs -verify %s + +??=pragma // expected-warning {{trigraph converted to '#' character}} + +int a = '??/0'; // expected-warning {{trigraph converted to '\' character}} + +int b = 1 ??' 0; // expected-warning {{trigraph converted to '^' character}} + +int c ??(1]; // expected-warning {{trigraph converted to '[' character}} + +int d [1??); // expected-warning {{trigraph converted to ']' character}} + +int e = 1 ??! 0; // expected-warning {{trigraph converted to '|' character}} + +void f() ??<} // expected-warning {{trigraph converted to '{' character}} + +void g() {??> // expected-warning {{trigraph converted to '}' character}} + +int h = ??- 0; // expected-warning {{trigraph converted to '~' character}} diff --git a/clang/test/CXX/lex/lex.trigraph/p2.cpp b/clang/test/CXX/lex/lex.trigraph/p2.cpp new file mode 100644 index 0000000..7d11d5b --- /dev/null +++ b/clang/test/CXX/lex/lex.trigraph/p2.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -trigraphs -Wtrigraphs -verify %s + +??=define arraycheck(a,b) a??(b??) ??!??! b??(a??) // expected-warning {{trigraph converted to '#' character}} expected-warning {{trigraph converted to '[' character}} expected-warning {{trigraph converted to ']' character}} expected-warning {{trigraph converted to '|' character}} expected-warning {{trigraph converted to '|' character}} expected-warning {{trigraph converted to '[' character}} expected-warning {{trigraph converted to ']' character}} diff --git a/clang/test/CXX/lex/lex.trigraph/p3.cpp b/clang/test/CXX/lex/lex.trigraph/p3.cpp new file mode 100644 index 0000000..2be0328 --- /dev/null +++ b/clang/test/CXX/lex/lex.trigraph/p3.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -trigraphs -Wtrigraphs -verify %s + +char a[] = +"?? ??\"??#??$??%??&??*??+??,??.??0??1??2??3??4??5??6" +"??7??8??9??:??;?????@??A??B??C??D??E??F??G??H??I??J" +"??K??L??M??N??O??P??Q??R??S??T??U??V??W??X??Y??Z??[" +"??\\??]??^??_??`??a??b??c??d??e??f??g??h??i??j??k??l" +"??m??n??o??p??q??r??s??t??u??v??w??x??y??z??{??|??}??~"; diff --git a/clang/test/CXX/over/over.built/p1.cpp b/clang/test/CXX/over/over.built/p1.cpp new file mode 100644 index 0000000..6000f5b --- /dev/null +++ b/clang/test/CXX/over/over.built/p1.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +enum E1 { one }; +enum E2 { two }; + +bool operator >= (E1, E1) { + return false; +} + +bool operator >= (E1, const E2) { + return false; +} + +bool test(E1 a, E1 b, E2 c) { + return a >= b || a >= c; +} diff --git a/clang/test/CXX/over/over.built/p23.cpp b/clang/test/CXX/over/over.built/p23.cpp new file mode 100644 index 0000000..4125521 --- /dev/null +++ b/clang/test/CXX/over/over.built/p23.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +struct Variant { + template operator T(); +}; + +Variant getValue(); + +void testVariant() { + bool ret1 = getValue() || getValue(); + bool ret2 = getValue() && getValue(); + bool ret3 = !getValue(); +} + +struct ExplicitVariant { + template explicit operator T(); +}; + +ExplicitVariant getExplicitValue(); + +void testExplicitVariant() { + bool ret1 = getExplicitValue() || getExplicitValue(); + bool ret2 = getExplicitValue() && getExplicitValue(); + bool ret3 = !getExplicitValue(); +} diff --git a/clang/test/CXX/over/over.built/p25.cpp b/clang/test/CXX/over/over.built/p25.cpp new file mode 100644 index 0000000..aea3854 --- /dev/null +++ b/clang/test/CXX/over/over.built/p25.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +enum class Color { Red, Green, Blue }; + +struct ConvertsToColorA { + operator Color(); +}; + +struct ConvertsToColorB { + operator Color(); +}; + +Color foo(bool cond, ConvertsToColorA ca, ConvertsToColorB cb) { + return cond? ca : cb; +} diff --git a/clang/test/CXX/over/over.load/p2-0x.cpp b/clang/test/CXX/over/over.load/p2-0x.cpp new file mode 100644 index 0000000..cf38741 --- /dev/null +++ b/clang/test/CXX/over/over.load/p2-0x.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Member function declarations with the same name and the same +// parameter-type-list as well as mem- ber function template +// declarations with the same name, the same parameter-type-list, and +// the same template parameter lists cannot be overloaded if any of +// them, but not all, have a ref-qualifier (8.3.5). + +class Y { + void h() &; + void h() const &; + void h() &&; + void i() &; // expected-note{{previous declaration}} + void i() const; // expected-error{{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&'}} + + template void f(T*) &; + template void f(T*) &&; + + template void g(T*) &; // expected-note{{previous declaration}} + template void g(T*); // expected-error{{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&'}} + + void k(); // expected-note{{previous declaration}} + void k() &&; // expected-error{{cannot overload a member function with ref-qualifier '&&' with a member function without a ref-qualifier}} +}; diff --git a/clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.list/p6.cpp b/clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.list/p6.cpp new file mode 100644 index 0000000..ea059ce --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.list/p6.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// rdar://problem/11120365 +namespace test0 { + template struct A { + static void foo(const T &t) {} + static void foo(T &&t) { + t.foo(); // expected-error {{member reference base type 'int' is not a structure or union}} + } + }; + + void test() { + A::foo({}); // expected-note {{requested here}} + } +} diff --git a/clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp b/clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp new file mode 100644 index 0000000..1c71468 --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.best/over.best.ics/over.ics.user/p3-0x.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +namespace PR6285 { + template struct identity + { typedef T type; }; + + struct D { + template + operator typename identity::type(); // expected-note{{candidate}} + }; + + int f() { return D(); } // expected-error{{no viable conversion}} +} + diff --git a/clang/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp b/clang/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp new file mode 100644 index 0000000..3971acc --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +namespace std_example { + int i; + int f1(); + int&& f2(); + int &g(const int &); + float &g(const int &&); + int &j = g(i); + float &k = g(f1()); + float &l = g(f2()); + + int &g2(const int &); + float &g2(int &&); + int &j2 = g2(i); + float &k2 = g2(f1()); + float &l2 = g2(f2()); + + // FIXME: We don't support ref-qualifiers yet. +#if 0 + struct A { + A& operator<<(int); + void p() &; + void p() &&; + }; + + A& operator<<(A&&, char); + A() << 1; + A() << 'c'; + A a; + a << 1; + a << 'c'; + A().p(); + a.p(); +#endif +} + +template +struct remove_reference { + typedef T type; +}; + +template +struct remove_reference { + typedef T type; +}; + +template +struct remove_reference { + typedef T type; +}; + +namespace FunctionReferencesOverloading { + template int &f(typename remove_reference::type&); + template float &f(typename remove_reference::type&&); + + void test_f(int (&func_ref)(int)) { + int &ir = f(func_ref); + } +} diff --git a/clang/test/CXX/over/over.match/over.match.best/p1.cpp b/clang/test/CXX/over/over.match/over.match.best/p1.cpp new file mode 100644 index 0000000..5c315a7 --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.best/p1.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template int &f0(T*, int); +float &f0(void*, int); + +void test_f0(int* ip, void *vp) { + // One argument is better... + int &ir = f0(ip, 0); + + // Prefer non-templates to templates + float &fr = f0(vp, 0); +} + +// Partial ordering of function template specializations will be tested +// elsewhere +// FIXME: Initialization by user-defined conversion is tested elsewhere diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.copy/p1.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.copy/p1.cpp new file mode 100644 index 0000000..31a679f --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.copy/p1.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify + +namespace ExplicitConv { + struct X { }; // expected-note 2{{candidate constructor}} + + struct Y { + explicit operator X() const; + }; + + void test(const Y& y) { + X x(static_cast(y)); + X x2((X)y); + X x3 = y; // expected-error{{no viable conversion from 'const ExplicitConv::Y' to 'ExplicitConv::X'}} + } +} + +namespace DR899 { + struct C { }; // expected-note 2 {{candidate constructor}} + + struct A { + explicit operator int() const; + explicit operator C() const; + }; + + struct B { + int i; + B(const A& a): i(a) { } + }; + + int main() { + A a; + int i = a; // expected-error{{no viable conversion}} + int j(a); + C c = a; // expected-error{{no viable conversion}} + C c2(a); + } +} diff --git a/clang/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp b/clang/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp new file mode 100644 index 0000000..3845af0 --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template T &lvalue(); +template T &&xvalue(); +template T prvalue(); + +struct X0 { + int &f() &; + float &f() &&; + + template int &ft(T) &; + template float &ft(T) &&; + + typedef int &(*func_int_ref)(); + typedef float &(*func_float_ref)(); + + operator func_int_ref() &; + operator func_float_ref() &&; + + void g(); + + int &operator+(const X0&) &; + float &operator+(const X0&) &&; + + template int &operator+(const T&) &; + template float &operator+(const T&) &&; + + int &h() const&; + float &h() &&; + int &h2() const&; + float &h2() const&&; +}; + +void X0::g() { + int &ir1 = f(); + int &ir2 = X0::f(); +} + +void test_ref_qualifier_binding() { + int &ir1 = lvalue().f(); + float &fr1 = xvalue().f(); + float &fr2 = prvalue().f(); + int &ir2 = lvalue().ft(1); + float &fr3 = xvalue().ft(2); + float &fr4 = prvalue().ft(3); +} + +void test_ref_qualifier_binding_with_surrogates() { + int &ir1 = lvalue()(); + float &fr1 = xvalue()(); + float &fr2 = prvalue()(); +} + +void test_ref_qualifier_binding_operators() { + int &ir1 = lvalue() + prvalue(); + float &fr1 = xvalue() + prvalue(); + float &fr2 = prvalue() + prvalue(); + int &ir2 = lvalue() + 1; + float &fr3 = xvalue() + 2; + float &fr4 = prvalue() + 3; +} + +void test_ref_qualifier_overloading() { + int &ir1 = lvalue().h(); + float &fr1 = xvalue().h(); + float &fr2 = prvalue().h(); + int &ir2 = lvalue().h2(); + float &fr3 = xvalue().h2(); + float &fr4 = prvalue().h2(); +} diff --git a/clang/test/CXX/over/over.oper/over.literal/p2.cpp b/clang/test/CXX/over/over.oper/over.literal/p2.cpp new file mode 100644 index 0000000..c012104 --- /dev/null +++ b/clang/test/CXX/over/over.oper/over.literal/p2.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +void operator "" _a(const char *); + +namespace N { + using ::operator "" _a; + + void operator "" _b(const char *); +} + +using N::operator "" _b; + +class C { + void operator "" _c(const char *); // expected-error {{must be in a namespace or global scope}} + + static void operator "" _c(unsigned long long); // expected-error {{must be in a namespace or global scope}} + + friend void operator "" _d(const char *); +}; + +int operator "" _e; // expected-error {{cannot be the name of a variable}} + +void f() { + int operator "" _f; // expected-error {{cannot be the name of a variable}} +} + +extern "C++" { + void operator "" _g(const char *); +} + +template void operator "" _h() {} + +template<> void operator "" _h<'a', 'b', 'c'>() {} + +template void operator "" _h<'a', 'b', 'c', 'd'>(); diff --git a/clang/test/CXX/over/over.oper/over.literal/p3.cpp b/clang/test/CXX/over/over.oper/over.literal/p3.cpp new file mode 100644 index 0000000..674ace9 --- /dev/null +++ b/clang/test/CXX/over/over.oper/over.literal/p3.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +using size_t = decltype(sizeof(int)); + +// Acceptable parameter declarations +char operator "" _a(const char *); +char operator "" _a(const char []); +char operator "" _a(unsigned long long); +char operator "" _a(long double); +char operator "" _a(char); +char operator "" _a(const volatile char); +char operator "" _a(wchar_t); +char operator "" _a(char16_t); +char operator "" _a(char32_t); +char operator "" _a(const char *, size_t); +char operator "" _a(const wchar_t *, size_t); +char operator "" _a(const char16_t *, size_t); +char operator "" _a(const char32_t *, size_t); +char operator "" _a(const char [32], size_t); + +// Unacceptable parameter declarations +char operator "" _b(); // expected-error {{parameter}} +char operator "" _b(const wchar_t *); // expected-error {{parameter}} +char operator "" _b(long long); // expected-error {{parameter}} +char operator "" _b(double); // expected-error {{parameter}} +char operator "" _b(short); // expected-error {{parameter}} +char operator "" _a(char, int = 0); // expected-error {{parameter}} +char operator "" _b(unsigned short); // expected-error {{parameter}} +char operator "" _b(signed char); // expected-error {{parameter}} +char operator "" _b(unsigned char); // expected-error {{parameter}} +char operator "" _b(const short *, size_t); // expected-error {{parameter}} +char operator "" _b(const unsigned short *, size_t); // expected-error {{parameter}} +char operator "" _b(const signed char *, size_t); // expected-error {{parameter}} +char operator "" _b(const unsigned char *, size_t); // expected-error {{parameter}} +char operator "" _a(const volatile char *, size_t); // expected-error {{parameter}} +char operator "" _a(volatile wchar_t *, size_t); // expected-error {{parameter}} +char operator "" _a(char16_t *, size_t); // expected-error {{parameter}} +char operator "" _a(const char32_t *, size_t, bool = false); // expected-error {{parameter}} +char operator "" _a(const char *, signed long); // expected-error {{parameter}} +char operator "" _a(const char *, size_t = 0); // expected-error {{default argument}} diff --git a/clang/test/CXX/over/over.oper/over.literal/p5.cpp b/clang/test/CXX/over/over.oper/over.literal/p5.cpp new file mode 100644 index 0000000..66f3f97 --- /dev/null +++ b/clang/test/CXX/over/over.oper/over.literal/p5.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +using size_t = decltype(sizeof(int)); +template struct S {}; + +template void operator "" _a(); +template S operator "" _a(); + +template struct U { + friend int operator "" _a(const char *, size_t); + // FIXME: It's not entirely clear whether this is intended to be legal. + friend U operator "" _a(const T *, size_t); // expected-error {{parameter}} +}; +template struct V { + friend void operator "" _b(); // expected-error {{parameter}} +}; + +template void operator "" _b(); // expected-error {{parameter}} +template void operator "" _b(int N = 0); // expected-error {{parameter}} +template void operator "" _b(); // expected-error {{parameter}} +template T operator "" _b(const char *); // expected-error {{parameter}} +template int operator "" _b(const T *, size_t); // expected-error {{parameter}} diff --git a/clang/test/CXX/over/over.oper/over.literal/p6.cpp b/clang/test/CXX/over/over.oper/over.literal/p6.cpp new file mode 100644 index 0000000..6bfb856 --- /dev/null +++ b/clang/test/CXX/over/over.oper/over.literal/p6.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +extern "C" void operator "" _a(const char *); // expected-error {{must have C++ linkage}} +extern "C" template void operator "" _b(); // expected-error {{must have C++ linkage}} + +extern "C" { + void operator "" _c(const char *); // expected-error {{must have C++ linkage}} + template void operator "" _d(); // expected-error {{must have C++ linkage}} + namespace N { + void operator "" _e(const char *); // expected-error {{must have C++ linkage}} + template void operator "" _f(); // expected-error {{must have C++ linkage}} + } +} diff --git a/clang/test/CXX/over/over.oper/over.literal/p7.cpp b/clang/test/CXX/over/over.oper/over.literal/p7.cpp new file mode 100644 index 0000000..72411b9 --- /dev/null +++ b/clang/test/CXX/over/over.oper/over.literal/p7.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +constexpr int operator "" _a(const char *c) { + return c[0]; +} + +static_assert(operator "" _a("foo") == 'f', ""); + +void puts(const char *); +static inline void operator "" _puts(const char *c) { + puts(c); +} +void f() { + operator "" _puts("foo"); + operator "" _puts("bar"); +} diff --git a/clang/test/CXX/over/over.oper/over.literal/p8.cpp b/clang/test/CXX/over/over.oper/over.literal/p8.cpp new file mode 100644 index 0000000..3f76082 --- /dev/null +++ b/clang/test/CXX/over/over.oper/over.literal/p8.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +struct string; +namespace std { + using size_t = decltype(sizeof(int)); +} + +void operator "" _km(long double); // ok +string operator "" _i18n(const char*, std::size_t); // ok +// FIXME: This should be accepted once we support UCNs +template int operator "" \u03C0(); // ok, UCN for lowercase pi // expected-error {{expected identifier}} +float operator ""E(const char *); // expected-error {{C++11 requires a space between literal and identifier}} expected-warning {{reserved}} +float operator " " B(const char *); // expected-error {{must be '""'}} expected-warning {{reserved}} +string operator "" 5X(const char *, std::size_t); // expected-error {{expected identifier}} +double operator "" _miles(double); // expected-error {{parameter}} +template int operator "" j(const char*); // expected-error {{parameter}} + +// FIXME: Accept this as an extension, with a fix-it to add the space +float operator ""_E(const char *); // expected-error {{C++11 requires a space between the "" and the user-defined suffix in a literal operator}} diff --git a/clang/test/CXX/over/over.over/p1.cpp b/clang/test/CXX/over/over.over/p1.cpp new file mode 100644 index 0000000..10c60da --- /dev/null +++ b/clang/test/CXX/over/over.over/p1.cpp @@ -0,0 +1,94 @@ +// RUN: %clang_cc1 -fsyntax-only %s + +template T f0(T); +int f0(int); + +// -- an object or reference being initialized +struct S { + int (*f0)(int); + float (*f1)(float); +}; + +void test_init_f0() { + int (*f0a)(int) = f0; + int (*f0b)(int) = &f0; + int (*f0c)(int) = (f0); + float (*f0d)(float) = f0; + float (*f0e)(float) = &f0; + float (*f0f)(float) = (f0); + int (&f0g)(int) = f0; + int (&f0h)(int) = (f0); + float (&f0i)(float) = f0; + float (&f0j)(float) = (f0); + S s = { f0, f0 }; +} + +// -- the left side of an assignment (5.17), +void test_assign_f0() { + int (*f0a)(int) = 0; + float (*f0b)(float) = 0; + + f0a = f0; + f0a = &f0; + f0a = (f0); + f0b = f0; + f0b = &f0; + f0b = (f0); +} + +// -- a parameter of a function (5.2.2), +void eat_f0(int a(int), float (*b)(float), int (&c)(int), float (&d)(float)); + +void test_pass_f0() { + eat_f0(f0, f0, f0, f0); + eat_f0(&f0, &f0, (f0), (f0)); +} + +// -- a parameter of a user-defined operator (13.5), +struct X { }; +void operator+(X, int(int)); +void operator-(X, float(*)(float)); +void operator*(X, int (&)(int)); +void operator/(X, float (&)(float)); + +void test_operator_pass_f0(X x) { + x + f0; + x + &f0; + x - f0; + x - &f0; + x * f0; + x * (f0); + x / f0; + x / (f0); +} + +// -- the return value of a function, operator function, or conversion (6.6.3), +int (*test_return_f0_a())(int) { return f0; } +int (*test_return_f0_b())(int) { return &f0; } +int (*test_return_f0_c())(int) { return (f0); } +float (*test_return_f0_d())(float) { return f0; } +float (*test_return_f0_e())(float) { return &f0; } +float (*test_return_f0_f())(float) { return (f0); } + +// -- an explicit type conversion (5.2.3, 5.2.9, 5.4), or +void test_convert_f0() { + (void)((int (*)(int))f0); + (void)((int (*)(int))&f0); + (void)((int (*)(int))(f0)); + (void)((float (*)(float))f0); + (void)((float (*)(float))&f0); + (void)((float (*)(float))(f0)); +} + +// -- a non-type template-parameter(14.3.2). +template struct Y0 { }; +template struct Y1 { }; +template struct Y2 { }; +template struct Y3 { }; + +Y0 y0; +Y0<&f0> y0a; +Y1 y1; +Y1<&f0> y1a; +Y2 y2; +Y3 y3; diff --git a/clang/test/CXX/over/over.over/p2-resolve-single-template-id.cpp b/clang/test/CXX/over/over.over/p2-resolve-single-template-id.cpp new file mode 100644 index 0000000..e021711 --- /dev/null +++ b/clang/test/CXX/over/over.over/p2-resolve-single-template-id.cpp @@ -0,0 +1,191 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion %s + +typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t; + +namespace DontResolveTooEarly_WaitForOverloadResolution +{ + template T* f(int); // #1 + template T& f(U); // #2 + + void g() { + int *ip = f(1); // calls #1 + } + + template + T* f2(int); + template + T& f2(U); + + void g2() { + int*ip = (f2)(1); // ok + } + +} // End namespace + +namespace DontAllowUnresolvedOverloadedExpressionInAnUnusedExpression +{ + void one() { } + template void oneT() { } + + void two() { } // expected-note 2 {{possible target for call}} + void two(int) { } // expected-note 2 {{possible target for call}} + template void twoT() { } // expected-note 2 {{possible target for call}} + template void twoT(T) { } // expected-note 2 {{possible target for call}} + + void check() + { + one; // expected-warning {{expression result unused}} + two; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} + oneT; // expected-warning {{expression result unused}} + twoT; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} + } + + // check the template function case + template void check() + { + one; // expected-warning {{expression result unused}} + two; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} + oneT; // expected-warning {{expression result unused}} + twoT; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} + + } + +} + + template + void twoT() { } + template + void twoT(T) { } + + + void two() { }; //expected-note 5{{candidate}} + void two(int) { }; //expected-note 5{{candidate}} + + + + void one() { } + template + void oneT() { } + + template + void cant_resolve() { } //expected-note 3{{candidate}} + + template void cant_resolve(T) { }//expected-note 3{{candidate}} + + +int main() +{ + + { static_cast(one); } + { (void)(one); } + { static_cast(oneT); } + { (void)(oneT); } + + { static_cast(two); } // expected-error {{address of overloaded function 'two' cannot be static_cast to type 'void'}} + { (void)(two); } // expected-error {{address of overloaded function 'two' cannot be cast to type 'void'}} + { static_cast(twoT); } + { (void)(twoT); } + + + { ptrdiff_t x = reinterpret_cast(oneT); } + { (void) reinterpret_cast(oneT); } + { (void) reinterpret_cast(one); } + { (void) reinterpret_cast(one); } + + { ptrdiff_t x = reinterpret_cast(twoT); } + { (void) reinterpret_cast(twoT); } + { (void) reinterpret_cast(two); } //expected-error {{reinterpret_cast}} + { (void) static_cast(two); } //ok + + { (void) reinterpret_cast(two); } //expected-error {{reinterpret_cast}} + { (void) reinterpret_cast(two); } //expected-error {{reinterpret_cast}} + + { bool b = (twoT); } + { bool b = (twoT); } + + { bool b = &twoT; //&foo; } + b = &(twoT); } + + { ptrdiff_t x = (ptrdiff_t) &twoT; + x = (ptrdiff_t) &twoT; } + + { ptrdiff_t x = (ptrdiff_t) twoT; + x = (ptrdiff_t) twoT; } + + + { ptrdiff_t x = (ptrdiff_t) &twoT; + x = (ptrdiff_t) &twoT; } + + { oneT; &oneT; } //expected-warning 2{{expression result unused}} + { static_cast(cant_resolve); } // expected-error {{address of overload}} + { bool b = cant_resolve; } // expected-error {{address of overload}} + { (void) cant_resolve; } // expected-error {{address of overload}} + +} + +namespace member_pointers { + struct S { + template bool f(T) { return false; } + template static bool g(T) { return false; } + + template bool h(T) { return false; } // expected-note 3 {{possible target for call}} + template static bool h(int) { return false; } // expected-note 3 {{possible target for call}} + }; + + void test(S s) { + if (S::f) return; // expected-error {{call to non-static member function without an object argument}} + if (S::f) return; // expected-error {{call to non-static member function without an object argument}} + if (&S::f) return; + if (&S::f) return; + if (s.f) return; // expected-error {{reference to non-static member function must be called}} + if (s.f) return; // expected-error {{reference to non-static member function must be called}} + if (&s.f) return; // expected-error {{cannot create a non-constant pointer to member function}} + if (&s.f) return; // expected-error {{cannot create a non-constant pointer to member function}} + + if (S::g) return; + if (S::g) return; + if (&S::g) return; + if (&S::g) return; + if (s.g) return; + if (s.g) return; + if (&s.g) return; + if (&s.g) return; + + if (S::h<42>) return; + if (S::h) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} + if (&S::h<42>) return; + if (&S::h) return; + if (s.h<42>) return; + if (s.h) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} + if (&s.h<42>) return; + if (&s.h) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} + + { bool b = S::f; } // expected-error {{call to non-static member function without an object argument}} + { bool b = S::f; } // expected-error {{call to non-static member function without an object argument}} + { bool b = &S::f; } + { bool b = &S::f; } + // These next two errors are terrible. + { bool b = s.f; } // expected-error {{reference to non-static member function must be called}} + { bool b = s.f; } // expected-error {{reference to non-static member function must be called}} + { bool b = &s.f; } // expected-error {{cannot create a non-constant pointer to member function}} + { bool b = &s.f; } // expected-error {{cannot create a non-constant pointer to member function}} + + { bool b = S::g; } + { bool b = S::g; } + { bool b = &S::g; } + { bool b = &S::g; } + { bool b = s.g; } + { bool b = s.g; } + { bool b = &s.g; } + { bool b = &s.g; } + + { bool b = S::h<42>; } + { bool b = S::h; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}} + { bool b = &S::h<42>; } + { bool b = &S::h; } + { bool b = s.h<42>; } + { bool b = s.h; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}} + { bool b = &s.h<42>; } + { bool b = &s.h; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}} + } +} diff --git a/clang/test/CXX/over/over.over/p2.cpp b/clang/test/CXX/over/over.over/p2.cpp new file mode 100644 index 0000000..3e8d0f1 --- /dev/null +++ b/clang/test/CXX/over/over.over/p2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template T f0(T, T); //expected-note{{candidate}} + +void test_f0() { + int (*f0a)(int, int) = f0; + int (*f0b)(int, int) = &f0; + int (*f0c)(int, float) = f0; // expected-error{{address of overloaded function 'f0' does not match required type 'int (int, float)'}} +} diff --git a/clang/test/CXX/over/over.over/p4.cpp b/clang/test/CXX/over/over.over/p4.cpp new file mode 100644 index 0000000..27d070e --- /dev/null +++ b/clang/test/CXX/over/over.over/p4.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template T f0(T); // expected-note{{candidate function}} +int f0(int); // expected-note{{candidate function}} + +void test_f0() { + int (*fp0)(int) = f0; + int (*fp1)(int) = &f0; + float (*fp2)(float) = &f0; +} + +namespace N { + int f0(int); // expected-note{{candidate function}} +} + +void test_f0_2() { + using namespace N; + int (*fp0)(int) = f0; // expected-error{{address of overloaded function 'f0' is ambiguous}} + float (*fp1)(float) = f0; +} diff --git a/clang/test/CXX/special/class.copy/implicit-move-def.cpp b/clang/test/CXX/special/class.copy/implicit-move-def.cpp new file mode 100644 index 0000000..5c54aea --- /dev/null +++ b/clang/test/CXX/special/class.copy/implicit-move-def.cpp @@ -0,0 +1,117 @@ +// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s +// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s +// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s + +// construct + +struct E { + E(); + E(E&&); +}; + +struct F { + F(); + F(F&&); +}; + +struct G { + E e; +}; + +struct H : G { + F l; + E m; + F ar[2]; +}; + +void f() { + H s; + // CHECK: call void @_ZN1HC1EOS_ + H t(static_cast(s)); +} + + +// assign + +struct A { + A &operator =(A&&); +}; + +struct B { + B &operator =(B&&); +}; + +struct C { + A a; +}; + +struct D : C { + A a; + B b; + A ar[2]; +}; + +void g() { + D d; + // CHECK: call {{.*}} @_ZN1DaSEOS_ + d = D(); +} + +// PR10822 +struct I { + unsigned var[1]; +}; + +// CHECK: define void @_Z1hv() nounwind { +void h() { + I i; + // CHECK: call void @llvm.memcpy. + i = I(); + // CHECK-NEXT: ret void +} + +// PR10860 +struct Empty { }; +struct VirtualWithEmptyBase : Empty { + virtual void f(); +}; + +// CHECK: define void @_Z25move_VirtualWithEmptyBaseR20VirtualWithEmptyBaseS0_ +void move_VirtualWithEmptyBase(VirtualWithEmptyBase &x, VirtualWithEmptyBase &y) { + // CHECK: call {{.*}} @_ZN20VirtualWithEmptyBaseaSEOS_ + x = static_cast(y); + // CHECK-NEXT: ret void +} + +// move assignment ops + +// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1DaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1CaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1BaSEOS_ +// array loop +// CHECK-ASSIGN: br i1 +// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_ + +// VirtualWithEmptyBase move assignment operatpr +// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN20VirtualWithEmptyBaseaSEOS_ +// CHECK-ASSIGN: store +// CHECK-ASSIGN-NEXT: store +// CHECK-ASSIGN-NOT: call +// CHECK-ASSIGN: ret + +// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1CaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_ + +// move ctors + +// CHECK-CTOR: define linkonce_odr {{.*}} @_ZN1HC2EOS_ +// CHECK-CTOR: call {{.*}} @_ZN1GC2EOS_ +// CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_ +// CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_ +// array loop +// CHECK-CTOR: br i1 +// CHECK-CTOR: call {{.*}} @_ZN1FC1EOS_ + +// CHECK-CTOR: define linkonce_odr {{.*}} @_ZN1GC2EOS_ +// CHECK-CTOR: call {{.*}} @_ZN1EC1EOS_ diff --git a/clang/test/CXX/special/class.copy/implicit-move.cpp b/clang/test/CXX/special/class.copy/implicit-move.cpp new file mode 100644 index 0000000..3e9accf --- /dev/null +++ b/clang/test/CXX/special/class.copy/implicit-move.cpp @@ -0,0 +1,236 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// Tests for implicit (non-)declaration of move constructor and +// assignment: p9, p11, p20, p23. + +// This class, used as a member, allows to distinguish move from copy because +// move operations are no-throw, copy operations aren't. +struct ThrowingCopy { + ThrowingCopy() noexcept; + ThrowingCopy(ThrowingCopy &&) noexcept; + ThrowingCopy(const ThrowingCopy &) noexcept(false); + ThrowingCopy & operator =(ThrowingCopy &&) noexcept; + ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false); +}; + +struct HasCopyConstructor { + ThrowingCopy tc; + HasCopyConstructor() noexcept; + HasCopyConstructor(const HasCopyConstructor &) noexcept(false); +}; + +struct HasCopyAssignment { + ThrowingCopy tc; + HasCopyAssignment() noexcept; + HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false); +}; + +struct HasMoveConstructor { + ThrowingCopy tc; + HasMoveConstructor() noexcept; + HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}} +}; + +struct HasMoveAssignment { // expected-note {{implicit copy constructor}} + ThrowingCopy tc; + HasMoveAssignment() noexcept; + HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept; +}; + +struct HasDestructor { + ThrowingCopy tc; + HasDestructor() noexcept; + ~HasDestructor() noexcept; +}; + +void test_basic_exclusion() { + static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), ""); + HasCopyConstructor hcc; + static_assert(!noexcept(hcc = HasCopyConstructor()), ""); + + static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), ""); + HasCopyAssignment hca; + static_assert(!noexcept(hca = HasCopyAssignment()), ""); + + static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), ""); + HasMoveConstructor hmc; + hmc = HasMoveConstructor(); // expected-error {{selected implicitly-deleted copy assignment}} + + (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}} + HasMoveAssignment hma; + static_assert(noexcept(hma = HasMoveAssignment()), ""); + + static_assert(!noexcept(HasDestructor((HasDestructor()))), ""); + HasDestructor hd; + static_assert(!noexcept(hd = HasDestructor()), ""); +} + +struct PrivateMove { + PrivateMove() noexcept; + PrivateMove(const PrivateMove &) noexcept(false); + PrivateMove & operator =(const PrivateMove &) noexcept(false); +private: + PrivateMove(PrivateMove &&) noexcept; + PrivateMove & operator =(PrivateMove &&) noexcept; +}; + +struct InheritsPrivateMove : PrivateMove {}; +struct ContainsPrivateMove { + PrivateMove pm; +}; + +struct PrivateDestructor { + PrivateDestructor() noexcept; + PrivateDestructor(const PrivateDestructor &) noexcept(false); + PrivateDestructor(PrivateDestructor &&) noexcept; +private: + ~PrivateDestructor() noexcept; +}; + +struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}} +struct ContainsPrivateDestructor { + PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}} +}; + +struct NonTrivialCopyOnly { + NonTrivialCopyOnly() noexcept; + NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false); + NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false); +}; + +struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {}; +struct ContainsNonTrivialCopyOnly { + NonTrivialCopyOnly ntco; +}; + +struct ContainsConst { + const int i; + ContainsConst() noexcept; + ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}} +}; + +struct ContainsRef { + int &i; + ContainsRef() noexcept; + ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}} +}; + +struct Base { + Base & operator =(Base &); +}; +struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}} +struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}} + +void test_deletion_exclusion() { + // FIXME: How to test the union thing? + + static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), ""); + static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), ""); + InheritsPrivateMove ipm; + static_assert(!noexcept(ipm = InheritsPrivateMove()), ""); + ContainsPrivateMove cpm; + static_assert(!noexcept(cpm = ContainsPrivateMove()), ""); + + (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}} + (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}} + + static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), ""); + static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), ""); + InheritsNonTrivialCopyOnly intco; + static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), ""); + ContainsNonTrivialCopyOnly cntco; + static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), ""); + + ContainsConst cc; + cc = ContainsConst(); // expected-error {{no viable}} + + ContainsRef cr; + cr = ContainsRef(); // expected-error {{no viable}} + + DirectVirtualBase dvb; + dvb = DirectVirtualBase(); // expected-error {{no viable}} + + IndirectVirtualBase ivb; + ivb = IndirectVirtualBase(); // expected-error {{no viable}} +} + +struct ContainsRValueRef { + int&& ri; + ContainsRValueRef() noexcept; +}; + +void test_contains_rref() { + (ContainsRValueRef(ContainsRValueRef())); +} + + +namespace DR1402 { + struct NonTrivialCopyCtor { + NonTrivialCopyCtor(const NonTrivialCopyCtor &); + }; + struct NonTrivialCopyAssign { + NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &); + }; + + struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor { + NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&); + NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default; + }; + struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign { + NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&); + NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default; + }; + + struct NonTrivialMoveAssign { + NonTrivialMoveAssign(NonTrivialMoveAssign&&); + NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&); + }; + struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign { + NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&); + NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default; + }; + + // A non-movable, non-trivially-copyable class type as a subobject inhibits + // the declaration of a move operation. + struct NoMove1 { NonTrivialCopyCtor ntcc; }; // expected-note 2{{'const DR1402::NoMove1 &'}} + struct NoMove2 { NonTrivialCopyAssign ntcc; }; // expected-note 2{{'const DR1402::NoMove2 &'}} + struct NoMove3 : NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove3 &'}} + struct NoMove4 : NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove4 &'}} + struct NoMove5 : virtual NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove5 &'}} + struct NoMove6 : virtual NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove6 &'}} + struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'const DR1402::NoMove7 &'}} + struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'const DR1402::NoMove8 &'}} + + // A non-trivially-move-assignable virtual base class inhibits the declaration + // of a move assignment (which might move-assign the base class multiple + // times). + struct NoMove9 : NonTrivialMoveAssign {}; + struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note {{'const DR1402::NoMove10 &'}} + struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'const DR1402::NoMove11 &'}} + + struct Test { + friend NoMove1::NoMove1(NoMove1 &&); // expected-error {{no matching function}} + friend NoMove2::NoMove2(NoMove2 &&); // expected-error {{no matching function}} + friend NoMove3::NoMove3(NoMove3 &&); // expected-error {{no matching function}} + friend NoMove4::NoMove4(NoMove4 &&); // expected-error {{no matching function}} + friend NoMove5::NoMove5(NoMove5 &&); // expected-error {{no matching function}} + friend NoMove6::NoMove6(NoMove6 &&); // expected-error {{no matching function}} + friend NoMove7::NoMove7(NoMove7 &&); // expected-error {{no matching function}} + friend NoMove8::NoMove8(NoMove8 &&); // expected-error {{no matching function}} + friend NoMove9::NoMove9(NoMove9 &&); + friend NoMove10::NoMove10(NoMove10 &&); + friend NoMove11::NoMove11(NoMove11 &&); + + friend NoMove1 &NoMove1::operator=(NoMove1 &&); // expected-error {{no matching function}} + friend NoMove2 &NoMove2::operator=(NoMove2 &&); // expected-error {{no matching function}} + friend NoMove3 &NoMove3::operator=(NoMove3 &&); // expected-error {{no matching function}} + friend NoMove4 &NoMove4::operator=(NoMove4 &&); // expected-error {{no matching function}} + friend NoMove5 &NoMove5::operator=(NoMove5 &&); // expected-error {{no matching function}} + friend NoMove6 &NoMove6::operator=(NoMove6 &&); // expected-error {{no matching function}} + friend NoMove7 &NoMove7::operator=(NoMove7 &&); // expected-error {{no matching function}} + friend NoMove8 &NoMove8::operator=(NoMove8 &&); // expected-error {{no matching function}} + friend NoMove9 &NoMove9::operator=(NoMove9 &&); + friend NoMove10 &NoMove10::operator=(NoMove10 &&); // expected-error {{no matching function}} + friend NoMove11 &NoMove11::operator=(NoMove11 &&); // expected-error {{no matching function}} + }; +} diff --git a/clang/test/CXX/special/class.copy/p11.0x.copy.cpp b/clang/test/CXX/special/class.copy/p11.0x.copy.cpp new file mode 100644 index 0000000..b2b4f6a --- /dev/null +++ b/clang/test/CXX/special/class.copy/p11.0x.copy.cpp @@ -0,0 +1,121 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct NonTrivial { + NonTrivial(const NonTrivial&); +}; + +// A defaulted copy constructor for a class X is defined as deleted if X has: + +// -- a variant member with a non-trivial corresponding constructor +union DeletedNTVariant { + NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant' is implicitly deleted because field 'NT' has a non-trivial copy constructor}} + DeletedNTVariant(); +}; +DeletedNTVariant DVa; +DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}} + +struct DeletedNTVariant2 { + union { + NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant2' is implicitly deleted because field 'NT' has a non-trivial copy constructor}} + }; + DeletedNTVariant2(); +}; +DeletedNTVariant2 DV2a; +DeletedNTVariant2 DV2b(DV2a); // expected-error{{call to implicitly-deleted copy constructor}} + +// -- a non-static data member of class type M (or array thereof) that cannot be +// copied because overload resolution results in an ambiguity or a function +// that is deleted or inaccessible +struct NoAccess { + NoAccess() = default; +private: + NoAccess(const NoAccess&); + + friend struct HasAccess; +}; + +struct HasNoAccess { + NoAccess NA; // expected-note{{copy constructor of 'HasNoAccess' is implicitly deleted because field 'NA' has an inaccessible copy constructor}} +}; +HasNoAccess HNAa; +HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}} + +struct HasAccess { + NoAccess NA; +}; + +HasAccess HAa; +HasAccess HAb(HAa); + +struct NonConst { + NonConst(NonConst&); +}; +struct Ambiguity { + Ambiguity(const Ambiguity&); + Ambiguity(volatile Ambiguity&); +}; + +struct IsAmbiguous { + NonConst NC; + Ambiguity A; // expected-note 2{{copy constructor of 'IsAmbiguous' is implicitly deleted because field 'A' has multiple copy constructors}} + IsAmbiguous(); +}; +IsAmbiguous IAa; +IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}} + +struct Deleted { + IsAmbiguous IA; // expected-note{{copy constructor of 'Deleted' is implicitly deleted because field 'IA' has a deleted copy constructor}} +}; +Deleted Da; +Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}} + +// -- a direct or virtual base class B that cannot be copied because overload +// resolution results in an ambiguity or a function that is deleted or +// inaccessible +struct AmbiguousCopyBase : Ambiguity { // expected-note 2{{copy constructor of 'AmbiguousCopyBase' is implicitly deleted because base class 'Ambiguity' has multiple copy constructors}} + NonConst NC; +}; +extern AmbiguousCopyBase ACBa; +AmbiguousCopyBase ACBb(ACBa); // expected-error {{deleted copy constructor}} + +struct DeletedCopyBase : AmbiguousCopyBase {}; // expected-note {{copy constructor of 'DeletedCopyBase' is implicitly deleted because base class 'AmbiguousCopyBase' has a deleted copy constructor}} +extern DeletedCopyBase DCBa; +DeletedCopyBase DCBb(DCBa); // expected-error {{deleted copy constructor}} + +struct InaccessibleCopyBase : NoAccess {}; // expected-note {{copy constructor of 'InaccessibleCopyBase' is implicitly deleted because base class 'NoAccess' has an inaccessible copy constructor}} +extern InaccessibleCopyBase ICBa; +InaccessibleCopyBase ICBb(ICBa); // expected-error {{deleted copy constructor}} + +// -- any direct or virtual base class or non-static data member of a type with +// a destructor that is deleted or inaccessible +struct NoAccessDtor { +private: + ~NoAccessDtor(); + friend struct HasAccessDtor; +}; + +struct HasNoAccessDtor { + NoAccessDtor NAD; // expected-note{{copy constructor of 'HasNoAccessDtor' is implicitly deleted because field 'NAD' has an inaccessible destructor}} + HasNoAccessDtor(); + ~HasNoAccessDtor(); +}; +HasNoAccessDtor HNADa; +HasNoAccessDtor HNADb(HNADa); // expected-error{{call to implicitly-deleted copy constructor}} + +struct HasAccessDtor { + NoAccessDtor NAD; +}; +HasAccessDtor HADa; +HasAccessDtor HADb(HADa); + +struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has an inaccessible destructor}} +}; +extern HasNoAccessDtorBase HNADBa; +HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}} + +// -- a non-static data member of rvalue reference type +struct RValue { + int && ri = 1; // expected-note{{copy constructor of 'RValue' is implicitly deleted because field 'ri' is of rvalue reference type 'int &&'}} +}; +RValue RVa; +RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}} diff --git a/clang/test/CXX/special/class.copy/p11.0x.move.cpp b/clang/test/CXX/special/class.copy/p11.0x.move.cpp new file mode 100644 index 0000000..ff9478b --- /dev/null +++ b/clang/test/CXX/special/class.copy/p11.0x.move.cpp @@ -0,0 +1,164 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct NonTrivial { + NonTrivial(NonTrivial&&); +}; + +// A defaulted move constructor for a class X is defined as deleted if X has: + +// -- a variant member with a non-trivial corresponding constructor +union DeletedNTVariant { + NonTrivial NT; + DeletedNTVariant(DeletedNTVariant&&); +}; +DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}} + +struct DeletedNTVariant2 { + union { + NonTrivial NT; + }; + DeletedNTVariant2(DeletedNTVariant2&&); +}; +DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}} + +// -- a non-static data member of class type M (or array thereof) that cannot be +// copied because overload resolution results in an ambiguity or a function +// that is deleted or inaccessible +struct NoAccess { + NoAccess() = default; +private: + NoAccess(NoAccess&&); + + friend struct HasAccess; +}; + +struct HasNoAccess { + NoAccess NA; + HasNoAccess(HasNoAccess&&); +}; +HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}} + +struct HasAccess { + NoAccess NA; + HasAccess(HasAccess&&); +}; +HasAccess::HasAccess(HasAccess&&) = default; + +struct Ambiguity { + Ambiguity(const Ambiguity&&); + Ambiguity(volatile Ambiguity&&); +}; + +struct IsAmbiguous { + Ambiguity A; + IsAmbiguous(IsAmbiguous&&); +}; +IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}} + +struct Deleted { + IsAmbiguous IA; + Deleted(Deleted&&); +}; +Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} + +// -- a direct or virtual base class B that cannot be moved because overload +// resolution results in an ambiguity or a function that is deleted or +// inaccessible +struct AmbiguousMoveBase : Ambiguity { + AmbiguousMoveBase(AmbiguousMoveBase&&); +}; +AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}} + +struct DeletedMoveBase : AmbiguousMoveBase { + DeletedMoveBase(DeletedMoveBase&&); +}; +DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}} + +struct InaccessibleMoveBase : NoAccess { + InaccessibleMoveBase(InaccessibleMoveBase&&); +}; +InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}} + +// -- any direct or virtual base class or non-static data member of a type with +// a destructor that is deleted or inaccessible +struct NoAccessDtor { + NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}} +private: + ~NoAccessDtor(); + friend struct HasAccessDtor; +}; + +struct HasNoAccessDtor { + NoAccessDtor NAD; + HasNoAccessDtor(HasNoAccessDtor&&); +}; +HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}} + +struct HasAccessDtor { + NoAccessDtor NAD; + HasAccessDtor(HasAccessDtor&&); +}; +HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default; + +struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}} +}; +extern HasNoAccessDtorBase HNADBa; +HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}} + +// The restriction on rvalue reference members applies to only the copy +// constructor. +struct RValue { + int &&ri = 1; + RValue(RValue&&); +}; +RValue::RValue(RValue&&) = default; + +// -- a non-static data member or direct or virtual base class with a type that +// does not have a move constructor and is not trivially copyable +struct CopyOnly { + CopyOnly(const CopyOnly&); +}; + +struct NonMove { + CopyOnly CO; + NonMove(NonMove&&); +}; +NonMove::NonMove(NonMove&&) = default; // ok under DR1402 + +struct Moveable { + Moveable(); + Moveable(Moveable&&); +}; + +struct HasMove { + Moveable M; + HasMove(HasMove&&); +}; +HasMove::HasMove(HasMove&&) = default; + +namespace DR1402 { + struct member { + member(); + member(const member&); + member& operator=(const member&); + ~member(); + }; + + struct A { + member m_; + + A() = default; + A(const A&) = default; + A& operator=(const A&) = default; + A(A&&) = default; + A& operator=(A&&) = default; + ~A() = default; + }; + + // ok, A's explicitly-defaulted move operations copy m_. + void f() { + A a, b(a), c(static_cast(a)); + a = b; + b = static_cast(c); + } +} diff --git a/clang/test/CXX/special/class.copy/p13-0x.cpp b/clang/test/CXX/special/class.copy/p13-0x.cpp new file mode 100644 index 0000000..0a9aa62 --- /dev/null +++ b/clang/test/CXX/special/class.copy/p13-0x.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// If the implicitly-defined constructor would satisfy the requirements of a +// constexpr constructor, the implicitly-defined constructor is constexpr. +struct Constexpr1 { + constexpr Constexpr1() : n(0) {} + int n; +}; +constexpr Constexpr1 c1a = Constexpr1(Constexpr1()); // ok +constexpr Constexpr1 c1b = Constexpr1(Constexpr1(c1a)); // ok + +struct Constexpr2 { + Constexpr1 ce1; + constexpr Constexpr2() = default; + constexpr Constexpr2(const Constexpr2 &o) : ce1(o.ce1) {} + // no move constructor +}; + +constexpr Constexpr2 c2a = Constexpr2(Constexpr2()); // ok +constexpr Constexpr2 c2b = Constexpr2(Constexpr2(c2a)); // ok + +struct Constexpr3 { + Constexpr2 ce2; + // all special constructors are constexpr, move ctor calls ce2's copy ctor +}; + +constexpr Constexpr3 c3a = Constexpr3(Constexpr3()); // ok +constexpr Constexpr3 c3b = Constexpr3(Constexpr3(c3a)); // ok + +struct NonConstexprCopy { + constexpr NonConstexprCopy() = default; + NonConstexprCopy(const NonConstexprCopy &); + constexpr NonConstexprCopy(NonConstexprCopy &&) = default; + + int n = 42; +}; + +NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // expected-note {{here}} + +constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy()); // ok +constexpr NonConstexprCopy ncc2 = ncc1; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} + +struct NonConstexprDefault { + NonConstexprDefault() = default; + constexpr NonConstexprDefault(int n) : n(n) {} + int n; +}; +struct Constexpr4 { + NonConstexprDefault ncd; +}; + +constexpr NonConstexprDefault ncd = NonConstexprDefault(NonConstexprDefault(1)); +constexpr Constexpr4 c4a = { ncd }; +constexpr Constexpr4 c4b = Constexpr4(c4a); +constexpr Constexpr4 c4c = Constexpr4(static_cast(const_cast(c4b))); + +struct Constexpr5Base {}; +struct Constexpr5 : Constexpr5Base { constexpr Constexpr5() {} }; +constexpr Constexpr5 ce5move = Constexpr5(); +constexpr Constexpr5 ce5copy = ce5move; diff --git a/clang/test/CXX/special/class.copy/p15-0x.cpp b/clang/test/CXX/special/class.copy/p15-0x.cpp new file mode 100644 index 0000000..fff8844 --- /dev/null +++ b/clang/test/CXX/special/class.copy/p15-0x.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +namespace PR10622 { + struct foo { + const int first; + foo(const foo&) = default; + }; + void find_or_insert(const foo& __obj) { + foo x(__obj); + } + + struct bar : foo { + bar(const bar&) = default; + }; + void test_bar(const bar &obj) { + bar obj2(obj); + } +} + +namespace PR11418 { + template + T may_throw() { + return T(); + } + + template T &&declval() noexcept; + + struct NonPOD { + NonPOD(); + NonPOD(const NonPOD &) noexcept; + NonPOD(NonPOD &&) noexcept; + }; + + struct X { + NonPOD np = may_throw(); + }; + + static_assert(noexcept(declval()), "noexcept isn't working at all"); + static_assert(noexcept(X(declval())), "copy constructor can't throw"); + static_assert(noexcept(X(declval())), "move constructor can't throw"); +} diff --git a/clang/test/CXX/special/class.copy/p15-inclass.cpp b/clang/test/CXX/special/class.copy/p15-inclass.cpp new file mode 100644 index 0000000..c4f8eaf --- /dev/null +++ b/clang/test/CXX/special/class.copy/p15-inclass.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s + +namespace PR11418 { + struct NonPOD { + NonPOD(); + NonPOD(const NonPOD &); + NonPOD(NonPOD &&); + }; + + struct X { + NonPOD np; + int a = 17; + }; + + void check_copy(X x) { + X x2(x); + } + + void check_move(X x) { + X x3(static_cast(x)); + } + + // CHECK: define linkonce_odr void @_ZN7PR114181XC2EOS0_ + // CHECK-NOT: 17 + // CHECK: call void @_ZN7PR114186NonPODC1EOS0_ + // CHECK-NOT: 17 + // CHECK: load i32* + // CHECK-NOT: 17 + // CHECK: store i32 + // CHECK-NOT: 17 + // CHECK: ret + + // CHECK: define linkonce_odr void @_ZN7PR114181XC2ERKS0_ + // CHECK-NOT: 17 + // CHECK: call void @_ZN7PR114186NonPODC1ERKS0_ + // CHECK-NOT: 17 + // CHECK: load i32* + // CHECK-NOT: 17 + // CHECK: store i32 + // CHECK-NOT: 17 + // CHECK: ret +} diff --git a/clang/test/CXX/special/class.copy/p20.cpp b/clang/test/CXX/special/class.copy/p20.cpp new file mode 100644 index 0000000..8dfb7ca --- /dev/null +++ b/clang/test/CXX/special/class.copy/p20.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct ConstCopy { + ConstCopy(); + ConstCopy &operator=(const ConstCopy&); +}; + +struct NonConstCopy { + NonConstCopy(); + NonConstCopy &operator=(NonConstCopy&); +}; + +struct VirtualInheritsNonConstCopy : virtual NonConstCopy { + VirtualInheritsNonConstCopy(); + VirtualInheritsNonConstCopy &operator=(const VirtualInheritsNonConstCopy&); +}; + +struct ImplicitNonConstCopy1 : NonConstCopy { // expected-note{{the implicit copy assignment operator}} + ImplicitNonConstCopy1(); +}; + +struct ImplicitNonConstCopy2 { // expected-note{{the implicit copy assignment operator}} + ImplicitNonConstCopy2(); + NonConstCopy ncc; +}; + +struct ImplicitNonConstCopy3 { // expected-note{{the implicit copy assignment operator}} + ImplicitNonConstCopy3(); + NonConstCopy ncc_array[2][3]; +}; + +struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { + ImplicitNonConstCopy4(); +}; + +void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1, + const ImplicitNonConstCopy2 &cincc2, + const ImplicitNonConstCopy3 &cincc3, + const ImplicitNonConstCopy4 &cincc4, + const VirtualInheritsNonConstCopy &vincc) { + (void)sizeof(ImplicitNonConstCopy1() = cincc1); // expected-error{{no viable overloaded '='}} + (void)sizeof(ImplicitNonConstCopy2() = cincc2); // expected-error{{no viable overloaded '='}} + (void)sizeof(ImplicitNonConstCopy3() = cincc3); // expected-error{{no viable overloaded '='}} + (void)sizeof(ImplicitNonConstCopy4() = cincc4); // okay + (void)sizeof(VirtualInheritsNonConstCopy() = vincc); +} diff --git a/clang/test/CXX/special/class.copy/p3.cpp b/clang/test/CXX/special/class.copy/p3.cpp new file mode 100644 index 0000000..3d87266 --- /dev/null +++ b/clang/test/CXX/special/class.copy/p3.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +// PR6141 +template +struct X { + X(); + template X(X); + X(const X&); +}; + +void f(X) { } + +struct Y : X { }; +struct Z : X { }; + +// CHECK: define i32 @main() +int main() { + // CHECK: call void @_ZN1YC1Ev + // CHECK: call void @_ZN1XIiEC1ERKS0_ + // CHECK: call void @_Z1f1XIiE + f(Y()); + // CHECK: call void @_ZN1ZC1Ev + // CHECK: call void @_ZN1XIfEC1ERKS0_ + // CHECK: call void @_ZN1XIiEC1IfEES_IT_E + // CHECK: call void @_Z1f1XIiE + f(Z()); +} diff --git a/clang/test/CXX/special/class.copy/p33-0x.cpp b/clang/test/CXX/special/class.copy/p33-0x.cpp new file mode 100644 index 0000000..b66e19a --- /dev/null +++ b/clang/test/CXX/special/class.copy/p33-0x.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -fsyntax-only -verify %s +class X { + X(const X&); + +public: + X(); + X(X&&); +}; + +X return_by_move(int i, X x) { + X x2; + if (i == 0) + return x; + else if (i == 1) + return x2; + else + return x; +} + +void throw_move_only(X x) { + X x2; + throw x; + throw x2; +} + +namespace PR10142 { + struct X { + X(); + X(X&&); + X(const X&) = delete; // expected-note 2{{function has been explicitly marked deleted here}} + }; + + void f(int i) { + X x; + try { + X x2; + if (i) + throw x2; // okay + throw x; // expected-error{{call to deleted constructor of 'PR10142::X'}} + } catch (...) { + } + } + + template + void f2(int i) { + T x; + try { + T x2; + if (i) + throw x2; // okay + throw x; // expected-error{{call to deleted constructor of 'PR10142::X'}} + } catch (...) { + } + } + + template void f2(int); // expected-note{{in instantiation of function template specialization 'PR10142::f2' requested here}} +} diff --git a/clang/test/CXX/special/class.copy/p8-cxx11.cpp b/clang/test/CXX/special/class.copy/p8-cxx11.cpp new file mode 100644 index 0000000..02e6cd1 --- /dev/null +++ b/clang/test/CXX/special/class.copy/p8-cxx11.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +// C++98 [class.copy]p5 / C++11 [class.copy]p8. + +// The implicitly-declared copy constructor for a class X will have the form +// X::X(const X&) +// if [every direct subobject] has a copy constructor whose first parameter is +// of type 'const volatile[opt] T &'. Otherwise, it will have the form +// X::X(X&) + +struct ConstCopy { + ConstCopy(const ConstCopy &); +}; + +struct NonConstCopy { + NonConstCopy(NonConstCopy &); +}; + +struct DeletedConstCopy { + DeletedConstCopy(const DeletedConstCopy &) = delete; +}; + +struct DeletedNonConstCopy { + DeletedNonConstCopy(DeletedNonConstCopy &) = delete; +}; + +struct ImplicitlyDeletedConstCopy { + ImplicitlyDeletedConstCopy(ImplicitlyDeletedConstCopy &&); +}; + + +struct A : ConstCopy {}; +struct B : NonConstCopy { ConstCopy a; }; +struct C : ConstCopy { NonConstCopy a; }; +struct D : DeletedConstCopy {}; +struct E : DeletedNonConstCopy {}; +struct F { ImplicitlyDeletedConstCopy a; }; +struct G : virtual B {}; + +struct Test { + friend A::A(const A &); + friend B::B(B &); + friend C::C(C &); + friend D::D(const D &); + friend E::E(E &); + friend F::F(const F &); + friend G::G(G &); +}; diff --git a/clang/test/CXX/special/class.copy/p9.cpp b/clang/test/CXX/special/class.copy/p9.cpp new file mode 100644 index 0000000..77ab19e --- /dev/null +++ b/clang/test/CXX/special/class.copy/p9.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct ConstCopy { + ConstCopy(); + ConstCopy(const ConstCopy&); +}; + +struct NonConstCopy { + NonConstCopy(); + NonConstCopy(NonConstCopy&); +}; + +struct VirtualInheritsNonConstCopy : virtual NonConstCopy { + VirtualInheritsNonConstCopy(); + VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&); +}; + +struct ImplicitNonConstCopy1 : NonConstCopy { // expected-note {{candidate constructor}} + ImplicitNonConstCopy1(); // expected-note {{candidate constructor}} +}; + +struct ImplicitNonConstCopy2 { // expected-note {{candidate constructor}} + ImplicitNonConstCopy2(); // expected-note {{candidate constructor}} + NonConstCopy ncc; +}; + +struct ImplicitNonConstCopy3 { // expected-note {{candidate constructor}} + ImplicitNonConstCopy3(); // expected-note {{candidate constructor}} + NonConstCopy ncc_array[2][3]; +}; + +struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { // expected-note {{candidate constructor}} + ImplicitNonConstCopy4(); // expected-note {{candidate constructor}} +}; + +void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1, + const ImplicitNonConstCopy2 &cincc2, + const ImplicitNonConstCopy3 &cincc3, + const ImplicitNonConstCopy4 &cincc4) { + (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy1' to 'ImplicitNonConstCopy1'}} + (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy2' to 'ImplicitNonConstCopy2'}} + (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy3' to 'ImplicitNonConstCopy3'}} + (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy4' to 'ImplicitNonConstCopy4'}} +} diff --git a/clang/test/CXX/special/class.ctor/p1.cpp b/clang/test/CXX/special/class.ctor/p1.cpp new file mode 100644 index 0000000..9500a7d --- /dev/null +++ b/clang/test/CXX/special/class.ctor/p1.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct X0 { + struct type { }; + + X0(); + X0(int); + (X0)(float); + X0 (f0)(int); + X0 (f0)(type); + + X0 f1(); + X0 f1(double); +}; + +X0::X0() { } +(X0::X0)(int) { } + +X0 (X0::f0)(int) { return X0(); } + +template +struct X1 { + struct type { }; + + X1(); + X1(int); + (X1)(float); + X1(float, float); + (X1)(double); + X1 (f0)(int); + X1 (f0)(type); + X1 (f1)(int); + X1 (f1)(type); + + template X1(U); + X1 f2(); + X1 f2(int); +}; + +template X1::X1() { } +template (X1::X1)(double) { } +template X1 X1::f1(int) { return 0; } +template X1 (X1::f1)(type) { return 0; } diff --git a/clang/test/CXX/special/class.ctor/p4-0x.cpp b/clang/test/CXX/special/class.ctor/p4-0x.cpp new file mode 100644 index 0000000..509beb4 --- /dev/null +++ b/clang/test/CXX/special/class.ctor/p4-0x.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// A constructor shall not be declared with a ref-qualifier. +struct X { + X() &; // expected-error{{ref-qualifier '&' is not allowed on a constructor}} + X(int) &&; // expected-error{{ref-qualifier '&&' is not allowed on a constructor}} +}; diff --git a/clang/test/CXX/special/class.ctor/p5-0x.cpp b/clang/test/CXX/special/class.ctor/p5-0x.cpp new file mode 100644 index 0000000..694ab5b --- /dev/null +++ b/clang/test/CXX/special/class.ctor/p5-0x.cpp @@ -0,0 +1,182 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +struct DefaultedDefCtor1 {}; +struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; }; +struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); }; // expected-note {{explicitly marked deleted here}} +class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); }; +struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note 4{{explicitly marked deleted here}} +class PrivateDtor { ~PrivateDtor() = default; }; +class Friend { + Friend() = default; ~Friend() = default; + friend struct NotDeleted6c; + friend struct NotDeleted7i; + friend struct NotDeleted7j; + friend struct NotDeleted7k; +}; +struct UserProvidedDefCtor { UserProvidedDefCtor() {} }; +int n; + + +// A defaulted default constructor for a class X is defined as deleted if: + +// - X is a union-like class that has a variant member with a non-trivial +// default constructor, +union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of union 'Deleted1a' is implicitly deleted because field 'u' has a non-trivial default constructor}} +Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}} +union NotDeleted1a { DefaultedDefCtor1 nu; }; +NotDeleted1a nd1a; +union NotDeleted1b { DefaultedDefCtor2 nu; }; +NotDeleted1b nd1b; + +// - any non-static data member with no brace-or-equal-initializer is of +// reference type, +class Deleted2a { + Deleted2a() = default; // expected-note 4{{implicitly deleted here}} + int &a; // expected-note 4{{because field 'a' of reference type 'int &' would not be initialized}} +}; +Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}} +struct Deleted2b { + int &&b; // expected-note {{default constructor of 'Deleted2b' is implicitly deleted because field 'b' of reference type 'int &&' would not be initialized}} +}; +Deleted2b d2b; // expected-error {{deleted default constructor}} +class NotDeleted2a { int &a = n; }; +NotDeleted2a nd2a; +class NotDeleted2b { int &a = error; }; // expected-error {{undeclared identifier}} +NotDeleted2b nd2b; +class NotDeleted2c { int &&a = 0; }; +NotDeleted2c nd2c; + +// - any non-variant non-static data member of const qualified type (or array +// thereof) with no brace-or-equal-initializer does not have a user-provided +// default constructor, +class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-qualified type 'const int' would not be initialized}} \ + expected-warning {{does not declare any constructor}} \ + expected-note {{will never be initialized}} +Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}} +class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1' would not be initialized}} +Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}} +class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}} +Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}} +class NotDeleted3a { const int a = 0; }; +NotDeleted3a nd3a; +class NotDeleted3b { const DefaultedDefCtor1 a[42] = {}; }; +NotDeleted3b nd3b; +class NotDeleted3c { const DefaultedDefCtor2 a = DefaultedDefCtor2(); }; +NotDeleted3c nd3c; +union NotDeleted3d { const int a; int b; }; +NotDeleted3d nd3d; +union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; }; +NotDeleted3e nd3e; +union NotDeleted3f { const DefaultedDefCtor2 a; int b; }; +NotDeleted3f nd3f; +struct NotDeleted3g { union { const int a; int b; }; }; +NotDeleted3g nd3g; + +// - X is a union and all of its variant members are of const-qualified type (or +// array thereof), +union Deleted4a { + const int a; + const int b; + const UserProvidedDefCtor c; // expected-note {{because field 'c' has a non-trivial default constructor}} +}; +Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}} +union NotDeleted4a { const int a; int b; }; +NotDeleted4a nd4a; + +// - X is a non-union class and all members of any anonymous union member are of +// const-qualified type (or array thereof), +struct Deleted5a { + union { const int a; }; // expected-note {{because all data members of an anonymous union member are const-qualified}} + union { int b; }; +}; +Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}} +struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; }; +NotDeleted5a nd5a; + +// - any direct or virtual base class, or non-static data member with no +// brace-or-equal-initializer, has class type M (or array thereof) and either +// M has no default constructor or overload resolution as applied to M's default +// constructor results in an ambiguity or in a function that is deleted or +// inaccessible from the defaulted default constructor, or +struct Deleted6a : Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}} +Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}} +struct Deleted6b : virtual Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}} +Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}} +struct Deleted6c { Deleted2a a; }; // expected-note {{because field 'a' has a deleted default constructor}} +Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}} +struct Deleted6d { DeletedDefCtor a; }; // expected-note {{because field 'a' has a deleted default constructor}} +Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}} +struct NotDeleted6a { DeletedDefCtor a = 0; }; +NotDeleted6a nd6a; +struct Deleted6e { PrivateDefCtor a; }; // expected-note {{because field 'a' has an inaccessible default constructor}} +Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}} +struct NotDeleted6b { PrivateDefCtor a = 0; }; +NotDeleted6b nd6b; +struct NotDeleted6c { Friend a; }; +NotDeleted6c nd6c; + +// - any direct or virtual base class or non-static data member has a type with +// a destructor that is deleted or inaccessible from the defaulted default +// constructor. +struct Deleted7a : DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}} +Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7b : virtual DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}} +Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7c { DeletedDtor a; }; // expected-note {{because field 'a' has a deleted destructor}} +Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{because field 'a' has a deleted destructor}} +Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7e : PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}} +Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7f : virtual PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}} +Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7g { PrivateDtor a; }; // expected-note {{field 'a' has an inaccessible destructor}} +Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}} +struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{field 'a' has an inaccessible destructor}} +Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}} +struct NotDeleted7i : Friend {}; +NotDeleted7i d7i; +struct NotDeleted7j : virtual Friend {}; +NotDeleted7j d7j; +struct NotDeleted7k { Friend a; }; +NotDeleted7k d7k; + + +class Trivial { static const int n = 42; }; +static_assert(__has_trivial_constructor(Trivial), "Trivial is nontrivial"); + +// A default constructor is trivial if it is not user-provided and if: +class NonTrivialDefCtor1 { NonTrivialDefCtor1(); }; +static_assert(!__has_trivial_constructor(NonTrivialDefCtor1), "NonTrivialDefCtor1 is trivial"); + +// - its class has no virtual functions (10.3) and no virtual base classes (10.1), and +class NonTrivialDefCtor2 { virtual void f(); }; +static_assert(!__has_trivial_constructor(NonTrivialDefCtor2), "NonTrivialDefCtor2 is trivial"); +class NonTrivialDefCtor3 : virtual Trivial {}; +static_assert(!__has_trivial_constructor(NonTrivialDefCtor3), "NonTrivialDefCtor3 is trivial"); + +// - no non-static data member of its class has a brace-or-equal-initializer, and +class NonTrivialDefCtor4 { int m = 52; }; +static_assert(!__has_trivial_constructor(NonTrivialDefCtor4), "NonTrivialDefCtor4 is trivial"); + +// - all the direct base classes of its class have trivial default constructors, and +class NonTrivialDefCtor5 : NonTrivialDefCtor1 {}; +static_assert(!__has_trivial_constructor(NonTrivialDefCtor5), "NonTrivialDefCtor5 is trivial"); + +// - for all the non-static data members of its class that are of class type (or array thereof), each such class +// has a trivial default constructor. +class NonTrivialDefCtor6 { NonTrivialDefCtor1 t; }; +static_assert(!__has_trivial_constructor(NonTrivialDefCtor6), "NonTrivialDefCtor5 is trivial"); + +// Otherwise, the default constructor is non-trivial. +class Trivial2 { Trivial2() = delete; }; +static_assert(__has_trivial_constructor(Trivial2), "Trivial2 is trivial"); + +class Trivial3 { Trivial3() = default; }; +static_assert(__has_trivial_constructor(Trivial3), "Trivial3 is trivial"); + +template class Trivial4 { Trivial4() = default; }; +static_assert(__has_trivial_constructor(Trivial4), "Trivial4 is trivial"); + +template class Trivial5 { Trivial5() = delete; }; +static_assert(__has_trivial_constructor(Trivial5), "Trivial5 is trivial"); diff --git a/clang/test/CXX/special/class.ctor/p6-0x.cpp b/clang/test/CXX/special/class.ctor/p6-0x.cpp new file mode 100644 index 0000000..8c8800f --- /dev/null +++ b/clang/test/CXX/special/class.ctor/p6-0x.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +// Implicitly-defined default constructors are constexpr if the implicit +// definition would be. +struct NonConstexpr1 { // expected-note {{here}} + int a; +}; +struct NonConstexpr2 { // expected-note {{here}} + NonConstexpr1 nl; +}; +struct NonConstexpr2a : NonConstexpr1 { }; +constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor +constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor +constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor +constexpr int nc2_a = NonConstexpr2().nl.a; // ok +constexpr int nc2a_a = NonConstexpr2a().a; // ok +struct Helper { + friend constexpr NonConstexpr1::NonConstexpr1(); // expected-error {{follows non-constexpr declaration}} + friend constexpr NonConstexpr2::NonConstexpr2(); // expected-error {{follows non-constexpr declaration}} +}; + +struct Constexpr1 {}; +constexpr Constexpr1 c1 = Constexpr1(); // ok +struct NonConstexpr3 : virtual Constexpr1 {}; // expected-note {{struct with virtual base}} expected-note {{declared here}} +constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{non-literal type 'const NonConstexpr3'}} + +struct Constexpr2 { + int a = 0; +}; +constexpr Constexpr2 c2 = Constexpr2(); // ok + +int n; +struct Member { + Member() : a(n) {} + constexpr Member(int&a) : a(a) {} + int &a; +}; +struct NonConstexpr4 { // expected-note {{here}} + Member m; +}; +constexpr NonConstexpr4 nc4 = NonConstexpr4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4'}} +struct Constexpr3 { + constexpr Constexpr3() : m(n) {} + Member m; +}; +constexpr Constexpr3 c3 = Constexpr3(); // ok +struct Constexpr4 { + Constexpr3 m; +}; +constexpr Constexpr4 c4 = Constexpr4(); // ok + + +// This rule breaks some legal C++98 programs! +struct A {}; // expected-note {{here}} +struct B { + friend A::A(); // expected-error {{non-constexpr declaration of 'A' follows constexpr declaration}} +}; diff --git a/clang/test/CXX/special/class.dtor/p10-0x.cpp b/clang/test/CXX/special/class.dtor/p10-0x.cpp new file mode 100644 index 0000000..e10afb5 --- /dev/null +++ b/clang/test/CXX/special/class.dtor/p10-0x.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// PR10127/N3031 +struct A { ~A(); }; +struct B {}; +template +void b(const T *x, const A *y) { + x->~decltype(T())(); + x->~decltype(*x)(); // expected-error{{the type of object expression ('const int') does not match the type being destroyed ('decltype(*x)' (aka 'const int &')) in pseudo-destructor expression}} \ + expected-error{{no member named '~const struct A &' in 'A'}} + x->~decltype(int())(); // expected-error{{no member named '~int' in 'A'}} + + y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}} + y->~decltype(T())(); // expected-error{{destructor type 'decltype(T())' in object destruction expression does not match the type 'const A' of the object being destroyed}} + y->~decltype(A())(); +} +template void b(const int*, const A*); // expected-note{{in instantiation of function template specialization 'b' requested here}} +template void b(const A*,const A*); // expected-note{{in instantiation of function template specialization 'b' requested here}} +void a(const A *x, int i, int *pi) { + x->~decltype(A())(); + x->~decltype(*x)(); // expected-error{{destructor type 'decltype(*x)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}} + x->~decltype()(); // expected-error{{expected expression}} + x->~decltype(B())(); // expected-error{{destructor type 'decltype(B())' (aka 'B') in object destruction expression does not match the type 'const A' of the object being destroyed}} + x->~decltype(x)(); // expected-error{{destructor type 'decltype(x)' (aka 'const A *') in object destruction expression does not match the type 'const A' of the object being destroyed}} + // this last one could be better, mentioning that the nested-name-specifier could be removed or a type name after the ~ + x->::A::~decltype(*x)(); // expected-error{{expected a class name after '~' to name a destructor}} + y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}} + + typedef int *intp; + i->~decltype(int())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} + i.~decltype(int())(); + i->~decltype(intp())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} \ + expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}} + i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}} + pi->~decltype(int())(); + pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}} + pi.~decltype(intp())(); + pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}} +} diff --git a/clang/test/CXX/special/class.dtor/p2-0x.cpp b/clang/test/CXX/special/class.dtor/p2-0x.cpp new file mode 100644 index 0000000..c7b1b58 --- /dev/null +++ b/clang/test/CXX/special/class.dtor/p2-0x.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// A destructor shall not be declared with a ref-qualifier. +struct X { + ~X() &; // expected-error{{ref-qualifier '&' is not allowed on a destructor}} +}; + +struct Y { + ~Y() &&; // expected-error{{ref-qualifier '&&' is not allowed on a destructor}} +}; diff --git a/clang/test/CXX/special/class.dtor/p2.cpp b/clang/test/CXX/special/class.dtor/p2.cpp new file mode 100644 index 0000000..b05c992 --- /dev/null +++ b/clang/test/CXX/special/class.dtor/p2.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR5548 +struct A {~A();}; +void a(const A* x) { + x->~A(); +} diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp new file mode 100644 index 0000000..44bf5aa --- /dev/null +++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp @@ -0,0 +1,177 @@ +// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s + +struct A { + ~A(); +}; + +struct B { + ~B() throw(int); +}; + +struct C { + B b; + ~C() {} +}; + +struct D { + ~D() noexcept(false); +}; + +struct E { + D d; + ~E() {} +}; + +void foo() { + A a; + C c; + E e; + // CHECK: invoke {{.*}} @_ZN1ED1Ev + // CHECK: invoke {{.*}} @_ZN1CD1Ev + // CHECK: call {{.*}} @_ZN1AD1Ev +} + +struct F { + D d; + ~F(); +}; +F::~F() noexcept(false) {} + +struct G { + D d; + ~G(); +}; +G::~G() {} + +struct H { + B b; + ~H(); +}; +H::~H() throw(int) {} + +struct I { + B b; + ~I(); +}; +I::~I() {} + +// Template variants. + +template +struct TA { + ~TA(); +}; + +template +struct TB { + ~TB() throw(int); +}; + +template +struct TC { + TB b; + ~TC() {} +}; + +template +struct TD { + ~TD() noexcept(false); +}; + +template +struct TE { + TD d; + ~TE() {} +}; + +void tfoo() { + TA a; + TC c; + TE e; + // CHECK: invoke {{.*}} @_ZN2TEIiED1Ev + // CHECK: invoke {{.*}} @_ZN2TCIiED1Ev + // CHECK: call {{.*}} @_ZN2TAIiED1Ev +} + +template +struct TF { + TD d; + ~TF(); +}; +template +TF::~TF() noexcept(false) {} + +template +struct TG { + TD d; + ~TG(); +}; +template +TG::~TG() {} + +template +struct TH { + TB b; + ~TH(); +}; +template +TH::~TH() {} + +void tinst() { + TF f; + TG g; + TH h; +} +// CHECK: define linkonce_odr {{.*}} @_ZN2THIiED1Ev +// CHECK: _ZTIi +// CHECK: __cxa_call_unexpected + +struct VX +{ virtual ~VX() {} }; + +struct VY : VX +{ virtual ~VY() {} }; + +template +struct TVY : VX +{ virtual ~TVY() {} }; + + +struct VA { + B b; + virtual ~VA() {} +}; + +struct VB : VA +{ virtual ~VB() {} }; + +template +struct TVB : VA +{ virtual ~TVB() {} }; + +void tinst2() { + TVY tvy; + TVB tvb; +} + +template +struct Sw { + T t; + ~Sw() {} +}; + +void tsw() { + Sw swi; + Sw swb; +} +// CHECK-NOT: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} nounwind +// CHECK: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} +// CHECK: _ZTIi +// CHECK: __cxa_call_unexpected +// CHECK: define linkonce_odr {{.*}} @_ZN2SwIiED1Ev({{.*}} nounwind + +template +struct TVC : VX +{ virtual ~TVC(); }; +template +TVC::~TVC() {} diff --git a/clang/test/CXX/special/class.dtor/p5-0x.cpp b/clang/test/CXX/special/class.dtor/p5-0x.cpp new file mode 100644 index 0000000..dbfa004 --- /dev/null +++ b/clang/test/CXX/special/class.dtor/p5-0x.cpp @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +struct NonTrivDtor { + ~NonTrivDtor(); +}; +struct DeletedDtor { + ~DeletedDtor() = delete; // expected-note 5 {{deleted here}} +}; +class InaccessibleDtor { + ~InaccessibleDtor() = default; +}; + +// A defaulted destructor for a class X is defined as deleted if: + +// -- X is a union-like class that has a variant member with a non-trivial +// destructor. +union A1 { + A1(); + NonTrivDtor n; // expected-note {{destructor of union 'A1' is implicitly deleted because field 'n' has a non-trivial destructor}} +}; +A1 a1; // expected-error {{deleted function}} +struct A2 { + A2(); + union { + NonTrivDtor n; // expected-note {{because field 'n' has a non-trivial destructor}} + }; +}; +A2 a2; // expected-error {{deleted function}} +union A3 { + A3(); + NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}} +}; +A3 a3; // expected-error {{deleted function}} +struct A4 { + A4(); + union { + NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}} + }; +}; +A4 a4; // expected-error {{deleted function}} + +// -- any of the non-static data members has class type M (or array thereof) and +// M has a deleted or inaccessible destructor. +struct B1 { + B1(); + DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}} +}; +B1 b1; // expected-error {{deleted function}} +struct B2 { + B2(); + InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}} +}; +B2 b2; // expected-error {{deleted function}} +struct B3 { + B3(); + DeletedDtor a[4]; // expected-note {{because field 'a' has a deleted destructor}} +}; +B3 b3; // expected-error {{deleted function}} +struct B4 { + B4(); + InaccessibleDtor a[4]; // expected-note {{because field 'a' has an inaccessible destructor}} +}; +B4 b4; // expected-error {{deleted function}} +union B5 { + B5(); + // FIXME: Describe the anonymous union member better than ''. + union { // expected-note {{because field '' has a deleted destructor}} + DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}} + }; +}; +B5 b5; // expected-error {{deleted function}} +union B6 { + B6(); + union { // expected-note {{because field '' has a deleted destructor}} + InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}} + }; +}; +B6 b6; // expected-error {{deleted function}} + +// -- any direct or virtual base class has a deleted or inaccessible destructor. +struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}} +struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}} +struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}} +struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}} + +// -- for a virtual destructor, lookup of the non-array deallocation function +// results in an ambiguity or a function that is deleted or inaccessible. +class D1 { + void operator delete(void*); +public: + virtual ~D1() = default; +} d1; // ok +struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} + // implicitly-virtual destructor +} d2; // expected-error {{deleted function}} +struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} + virtual ~D3() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}} + void operator delete(void*, double = 0.0); + void operator delete(void*, char = 0); +} d3; // expected-error {{deleted function}} +struct D4 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} + virtual ~D4() = default; // expected-note {{implicitly deleted here}} + void operator delete(void*) = delete; +} d4; // expected-error {{deleted function}} diff --git a/clang/test/CXX/special/class.dtor/p9.cpp b/clang/test/CXX/special/class.dtor/p9.cpp new file mode 100644 index 0000000..8b76a15 --- /dev/null +++ b/clang/test/CXX/special/class.dtor/p9.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef typeof(sizeof(int)) size_t; + +// PR7803 +namespace test0 { + class A { + public: + static void operator delete(void *p) {}; + virtual ~A(); + }; + + class B : protected A { + public: + ~B(); + }; + + class C : protected B { + public: + using B::operator delete; + ~C(); + }; + + // Shouldn't have an error. + C::~C() {} +} + +namespace test1 { + class A { + public: + static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}} + virtual ~A(); + }; + + class B : protected A { + public: + static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}} + ~B(); + }; + + class C : protected B { + public: + using A::operator delete; + using B::operator delete; + + ~C(); + }; + + C::~C() {} // expected-error {{multiple suitable 'operator delete' functions in 'C'}} +} + +// ...at the point of definition of a virtual destructor... +namespace test2 { + struct A { + virtual ~A(); + static void operator delete(void*, const int &); + }; + + struct B { + virtual ~B(); + static void operator delete(void*, const int &); // expected-note {{declared here}} + }; + B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}} + + struct CBase { virtual ~CBase(); }; + struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}} + static void operator delete(void*, const int &); // expected-note {{declared here}} + }; + void test() { + C c; // expected-note {{first required here}} + } +} + +// PR7346 +namespace test3 { + struct A { + virtual ~A(); + static void operator delete(void*, const int &); + }; + + struct B : A { + virtual ~B() {} + static void operator delete(void*); + }; +} diff --git a/clang/test/CXX/special/class.free/p1.cpp b/clang/test/CXX/special/class.free/p1.cpp new file mode 100644 index 0000000..5c0240b --- /dev/null +++ b/clang/test/CXX/special/class.free/p1.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +#include + +struct A { + void *operator new(size_t) { + return this; // expected-error {{invalid use of 'this' outside of a non-static member function}} + } + void *operator new[](size_t) { + return this; // expected-error {{invalid use of 'this' outside of a non-static member function}} + } +}; diff --git a/clang/test/CXX/special/class.free/p6.cpp b/clang/test/CXX/special/class.free/p6.cpp new file mode 100644 index 0000000..fc4b2ae --- /dev/null +++ b/clang/test/CXX/special/class.free/p6.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +#include + +struct A { + void operator delete(void*) { + (void)this; // expected-error {{invalid use of 'this' outside of a non-static member function}} + } + void operator delete[](void*) { + (void)this; // expected-error {{invalid use of 'this' outside of a non-static member function}} + } +}; diff --git a/clang/test/CXX/special/class.inhctor/elsewhere.cpp b/clang/test/CXX/special/class.inhctor/elsewhere.cpp new file mode 100644 index 0000000..09fd3d5 --- /dev/null +++ b/clang/test/CXX/special/class.inhctor/elsewhere.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Tests related to constructor inheriting, but not specified in [class.inhctor] + +// [namespace.udecl]p8: +// A using-declaration for a class member shall be a member-declaration. + +struct B1 { + B1(int); +}; + +using B1::B1; // expected-error {{using declaration can not refer to class member}} expected-error {{not supported}} + +// C++0x [namespace.udecl]p10: +// A using-declaration is a declaration and can therefore be used repeatedly +// where (and only where) multiple declarations are allowed. + +struct I1 : B1 { + using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}} + using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}} +}; + +// C++0x [namespace.udecl]p3: +// In a using declaration used as a member-declaration, the nested-name- +// specifier shall name a base class of the class being defined. +// If such a using-declaration names a constructor, the nested-name-specifier +// shall name a direct base class of the class being defined. + +struct D1 : I1 { + using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} expected-error {{not supported}} +}; + +template struct A {}; + +template struct B : A, A { + using A::A; // expected-error {{'A::', which is not a base class of 'B'}} expected-error {{not supported}} +}; +B bb; +B bc; +B bd; // expected-note {{here}} + +template struct C : A { + using A::A; // expected-error {{'A::', which is not a base class of 'C'}} expected-error {{not supported}} +}; +C cb; +C cc; // expected-note {{here}} + +template struct D : A {}; +template struct E : D { + using A::A; // expected-error {{'A' is not a direct base of 'E', can not inherit}} expected-error {{not supported}} +}; +E eb; // expected-note {{here}} + +template struct F : D { + using A::A; // expected-error {{'A' is not a direct base of 'F'}} expected-error {{not supported}} +}; +F fb; // expected-note {{here}} diff --git a/clang/test/CXX/special/class.inhctor/p3.cpp b/clang/test/CXX/special/class.inhctor/p3.cpp new file mode 100644 index 0000000..d7093fb --- /dev/null +++ b/clang/test/CXX/special/class.inhctor/p3.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct B1 { + B1(int); + B1(int, int); +}; +struct D1 : B1 { + using B1::B1; // expected-error {{not supported}} +}; +D1 d1a(1), d1b(1, 1); + +D1 fd1() { return 1; } + +struct B2 { + explicit B2(int, int = 0, int = 0); +}; +struct D2 : B2 { // expected-note 2 {{candidate constructor}} + using B2::B2; // expected-error {{not supported}} +}; +D2 d2a(1), d2b(1, 1), d2c(1, 1, 1); + +D2 fd2() { return 1; } // expected-error {{no viable conversion}} + +struct B3 { + B3(void*); // expected-note {{inherited from here}} +}; +struct D3 : B3 { // expected-note 2 {{candidate constructor}} + using B3::B3; // expected-note {{candidate constructor (inherited)}} expected-error {{not supported}} +}; +D3 fd3() { return 1; } // expected-error {{no viable conversion}} + +template struct T1 : B1 { + using B1::B1; // expected-error {{not supported}} +}; +template struct T2 : T1 { + using T1::T1; // expected-error {{not supported}} +}; +template struct T3 : T1 { + using T1::T1; // expected-error {{not supported}} +}; +struct U { + friend T1::T1(int); + friend T1::T1(int, int); + friend T2::T2(int); + friend T2::T2(int, int); + friend T3::T3(int); + friend T3::T3(int, int); +}; diff --git a/clang/test/CXX/special/class.inhctor/p7.cpp b/clang/test/CXX/special/class.inhctor/p7.cpp new file mode 100644 index 0000000..bfaa3ac --- /dev/null +++ b/clang/test/CXX/special/class.inhctor/p7.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Straight from the standard +struct B1 { + B1(int); // expected-note {{previous constructor}} expected-note {{conflicting constructor}} +}; +struct B2 { + B2(int); // expected-note {{conflicting constructor}} +}; +struct D1 : B1, B2 { + using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}} + using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}} +}; +struct D2 : B1, B2 { + using B1::B1; // expected-error {{not supported}} + using B2::B2; // expected-error {{not supported}} + D2(int); +}; + +template struct B3 { + B3(T); // expected-note {{previous constructor}} +}; +template struct B4 : B3, B1 { + B4(); + using B3::B3; // expected-note {{inherited here}} expected-error {{not supported}} + using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}} +}; +B4 b4c; +B4 b4i; // expected-note {{here}} diff --git a/clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp b/clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp new file mode 100644 index 0000000..a108533 --- /dev/null +++ b/clang/test/CXX/special/class.init/class.base.init/p8-0x.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +int n; +struct S { + int &a; // expected-note 2{{here}} + int &b = n; + + union { + const int k = 42; + }; + + S() {} // expected-error {{constructor for 'S' must explicitly initialize the reference member 'a'}} + S(int) : a(n) {} // ok + S(char) : b(n) {} // expected-error {{constructor for 'S' must explicitly initialize the reference member 'a'}} + S(double) : a(n), b(n) {} // ok +} s(0); + +union U { + int a = 0; // desired-note 5 {{previous initialization is here}} + char b = 'x'; + + // FIXME: these should all be rejected + U() {} // desired-error {{initializing multiple members of union}} + U(int) : a(1) {} // desired-error {{initializing multiple members of union}} + U(char) : b('y') {} // desired-error {{initializing multiple members of union}} + // this expected note should be removed & the note should appear on the + // declaration of 'a' when this set of cases is handled correctly. + U(double) : a(1), // expected-note{{previous initialization is here}} desired-error {{initializing multiple members of union}} + b('y') {} // expected-error{{initializing multiple members of union}} +}; + +// PR10954: variant members do not acquire an implicit initializer. +namespace VariantMembers { + struct NoDefaultCtor { + NoDefaultCtor(int); + }; + union V { + NoDefaultCtor ndc; + int n; + + V() {} + V(int n) : n(n) {} + V(int n, bool) : ndc(n) {} + }; + struct K { + union { + NoDefaultCtor ndc; + int n; + }; + K() {} + K(int n) : n(n) {} + K(int n, bool) : ndc(n) {} + }; + struct Nested { + Nested() {} + union { + struct { + NoDefaultCtor ndc; + }; + }; + }; +} diff --git a/clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp b/clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp new file mode 100644 index 0000000..ca5e807 --- /dev/null +++ b/clang/test/CXX/special/class.init/class.base.init/p9-0x.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++11 %s -O1 -emit-llvm -o - | FileCheck %s + +struct S { + int n = 10; + int m = 2 * n; + + S() {} + S(int a) : n(a) {} + S(int a, int b) : n(a), m(b) {} + + struct T { + T *that = this; + }; +}; + +template +struct U { + T *r = &q; + T q = 42; + U *p = this; +}; + +S a; +// CHECK: @a = {{.*}} { i32 10, i32 20 } + +S b(5); +// CHECK: @b = {{.*}} { i32 5, i32 10 } + +S c(3, 9); +// CHECK: @c = {{.*}} { i32 3, i32 9 } + +S::T d; +// CHECK: @d = {{.*}} { {{.*}} @d } + +U e; +// CHECK: @e = {{.*}} { {{.*}} { i32 42, i32 84 }, {{.*}} @e } diff --git a/clang/test/CXX/special/class.temporary/p1.cpp b/clang/test/CXX/special/class.temporary/p1.cpp new file mode 100644 index 0000000..4f6ac0a --- /dev/null +++ b/clang/test/CXX/special/class.temporary/p1.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace test0 { + struct A { + A() = default; + int x; + int y; + + A(const A&) = delete; // expected-note {{function has been explicitly marked deleted here}} + }; + + void foo(...); + + void test() { + A a; + foo(a); // expected-error {{call to deleted constructor of 'test0::A'}} + } +} + +namespace test1 { + struct A { + A() = default; + int x; + int y; + + private: + A(const A&) = default; // expected-note {{declared private here}} + }; + + void foo(...); + + void test() { + A a; + foo(a); // expected-error {{calling a private constructor of class 'test1::A'}} + } +} + +// Don't enforce this in an unevaluated context. +namespace test2 { + struct A { + A(const A&) = delete; // expected-note {{marked deleted here}} + }; + + typedef char one[1]; + typedef char two[2]; + + one &meta(bool); + two &meta(...); + + void a(A &a) { + char check[sizeof(meta(a)) == 2 ? 1 : -1]; + } + + void b(A &a) { + meta(a); // expected-error {{call to deleted constructor}} + } +} diff --git a/clang/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp b/clang/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp new file mode 100644 index 0000000..81e8e25 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.ambig/p1-0x.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct T { + struct x { + int m; + }; + x* operator->(); + void operator++(int); + void operator<<(int); + T(); + T(int); + T(int, int); +}; + +template +void func(A, B, C, D, E); + +void func(int a, int c) { + T(a)->m = 7; + T(a)++; + T(a,5)<m = 7; + decltype(T())(a)++; + decltype(T())(a,5)< 3) + goto end; + + X x; + X xs[16]; + exx(x); + + end: + if (argc > 1) { + for (int i = 0; i < argc; ++i) + { + + } + } + return 0; +} + +struct Y { + ~Y(); +}; + +void f(); +void test_Y() { + goto end; // expected-error{{goto into protected scope}} + Y y; // expected-note{{jump bypasses variable with a non-trivial destructor}} + end: + f(); + goto inner; // expected-error{{goto into protected scope}} + { + Y y2; // expected-note{{jump bypasses variable with a non-trivial destructor}} + inner: + f(); + } + return; +} + +struct Z { + Z operator=(const Z&); +}; + +void test_Z() { + goto end; + Z z; + end: + return; +} diff --git a/clang/test/CXX/stmt.stmt/stmt.dcl/p3.cpp b/clang/test/CXX/stmt.stmt/stmt.dcl/p3.cpp new file mode 100644 index 0000000..f52e3b6 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.dcl/p3.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR10034 +struct X {}; + +void exx(X) {} + +int test_ptr10034(int argc, char **argv) +{ + if (argc > 3) + goto end; + + X x; + X xs[16]; + exx(x); + + end: + if (argc > 1) { + for (int i = 0; i < argc; ++i) + { + + } + } + return 0; +} + +struct Y { + ~Y(); +}; + +void test_Y() { + goto end; // expected-error{{goto into protected scope}} + Y y; // expected-note{{jump bypasses variable with a non-trivial destructor}} + end: + return; +} + +struct Z { + Z operator=(const Z&); +}; + +void test_Z() { + goto end; // expected-error{{goto into protected scope}} + Z z; // expected-note{{jump bypasses initialization of non-POD variable}} + end: + return; +} diff --git a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp new file mode 100644 index 0000000..a45b35f --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -0,0 +1,209 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace std { + template + auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}} + template + auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} + + template + auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \ + expected-note 4{{candidate template ignored: substitution failure [with T = }} + template + auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} + + namespace inner { + // These should never be considered. + int begin(int); + int end(int); + } + + using namespace inner; +} + +struct A { // expected-note 2 {{candidate constructor}} + A(); + int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}} + int *end(); +}; + +struct B { + B(); + int *alt_begin(); + int *alt_end(); +}; + +void f(); +void f(int); + +void g() { + for (int a : A()) + A __begin; + for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} + } + for (char *a : B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} + } + // FIXME: Terrible diagnostic here. auto deduction should fail, but does not! + for (double a : f) { // expected-error {{cannot use type '' as a range}} + } + for (auto a : A()) { + } + for (auto a : B()) { + } + for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}} + } + // : is not a typo for :: here. + for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'A'}} + } + for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}} + } + + for (auto a : A()) + for (auto b : A()) { + __range.begin(); // expected-error {{use of undeclared identifier '__range'}} + ++__begin; // expected-error {{use of undeclared identifier '__begin'}} + --__end; // expected-error {{use of undeclared identifier '__end'}} + } + + for (char c : "test") + ; + for (auto a : f()) // expected-error {{cannot use type 'void' as a range}} + ; + + extern int incomplete[]; + for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}} + ; + extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}} + for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}} + ; + + struct VoidBegin { + void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}} + void end(); + }; + for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}} + ; + + struct null_t { + operator int*(); + }; + struct Differ { + int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}} + null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}} + }; + for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}} + ; + + for (void f() : "error") // expected-error {{for range declaration must declare a variable}} + ; + + for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}} + for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}} + for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} + for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}} + + struct NoBeginADL { + null_t alt_end(); + }; + struct NoEndADL { + null_t alt_begin(); + }; + for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}} + } + for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}} + } + + struct NoBegin { + null_t end(); + }; + struct NoEnd { + null_t begin(); + }; + for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}} + } + for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} + } + + struct NoIncr { + void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} + void *end(); + }; + for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}} + } + + struct NoNotEq { + NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}} + NoNotEq end(); + void operator++(); + }; + for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}} + } + + struct NoCopy { + NoCopy(); + NoCopy(const NoCopy &) = delete; + int *begin(); + int *end(); + }; + for (int n : NoCopy()) { // ok + } + + for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \ + expected-note {{range has type 'int'}} + } + + for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}} + } +} + +template +void h(T t) { + for (U u : t) { // expected-error {{no viable conversion from 'A' to 'int'}} + } + for (auto u : t) { + } +} + +template void h(A); +template void h(A(&)[4]); +template void h(A(&)[13]); +template void h(A(&)[13]); // expected-note {{requested here}} + +template +void i(T t) { + for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \ + expected-error {{member function 'begin' not viable}} \ + expected-note {{range has type}} + } +} +template void i(A*); // expected-note {{requested here}} +template void i(const A); // expected-note {{requested here}} + +namespace NS { + class ADL {}; + int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}} + int *end(ADL); + + class NoADL {}; +} +int *begin(NS::NoADL); +int *end(NS::NoADL); + +struct VoidBeginADL {}; +void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}} +void end(VoidBeginADL); + +void j() { + for (auto u : NS::ADL()) { + } + for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}} + } + for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}} + } +} + +void example() { + int array[5] = { 1, 2, 3, 4, 5 }; + for (int &x : array) + x *= 2; +} diff --git a/clang/test/CXX/stmt.stmt/stmt.label/p1.cpp b/clang/test/CXX/stmt.stmt/stmt.label/p1.cpp new file mode 100644 index 0000000..90367f8 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.label/p1.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f() +{ + int x = 0; + goto label1; + +label1: // expected-note{{previous definition is here}} + x = 1; + goto label2; // expected-error{{use of undeclared label 'label2'}} + +label1: // expected-error{{redefinition of label 'label1'}} + x = 2; +} + +void h() +{ + int x = 0; + switch (x) + { + case 1:; + default:; // expected-error{{multiple default labels in one switch}} + default:; // expected-note{{previous case defined here}} + } +} diff --git a/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp b/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp new file mode 100644 index 0000000..35e5c91 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int f(); + +void g() { + if (int x = f()) { // expected-note 2{{previous definition}} + int x; // expected-error{{redefinition of 'x'}} + } else { + int x; // expected-error{{redefinition of 'x'}} + } +} + + +void h() { + if (int x = f()) // expected-note 2{{previous definition}} + int x; // expected-error{{redefinition of 'x'}} + else + int x; // expected-error{{redefinition of 'x'}} +} diff --git a/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp b/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp new file mode 100644 index 0000000..000c870 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +struct Value { + constexpr Value(int n) : n(n) {} + constexpr operator short() { return n; } + int n; +}; +enum E { E0, E1 }; +struct Alt { + constexpr operator E() { return E0; } +}; + +constexpr short s = Alt(); + +void test(Value v) { + switch (v) { + case Alt(): + case E1: + case Value(2): + case 3: + break; + } + switch (Alt a = Alt()) { + case Alt(): + case E1: + case Value(2): + case 3: + break; + } + switch (E0) { + case Alt(): + case E1: + // FIXME: These should produce a warning that 2 and 3 are not values of the + // enumeration. + case Value(2): + case 3: + break; + } +} diff --git a/clang/test/CXX/temp/p3.cpp b/clang/test/CXX/temp/p3.cpp new file mode 100644 index 0000000..c146bc4 --- /dev/null +++ b/clang/test/CXX/temp/p3.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -verify %s + +template struct S { + static int a, b; +}; + +template int S::a, S::b; // expected-error {{can only declare a single entity}} + +template struct A { static A a; } A::a; // expected-error {{expected ';' after struct}} \ + expected-error {{use of undeclared identifier 'T'}} \ + expected-warning{{extra qualification}} + +template struct B { } f(); // expected-error {{expected ';' after struct}} \ + expected-error {{requires a type specifier}} + +template struct C { } // expected-error {{expected ';' after struct}} + +A c; diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp new file mode 100644 index 0000000..59ce8b6 --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify + +namespace std { + typedef decltype(nullptr) nullptr_t; +} + +template struct IP { // expected-note 4 {{template parameter is declared here}} + IP *ip2; +}; + +constexpr std::nullptr_t get_nullptr() { return nullptr; } + +constexpr std::nullptr_t np = nullptr; + +std::nullptr_t nonconst_np; // expected-note{{declared here}} + +IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} +IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} +IP ip2; +IP ip3; +IP<(int*)0> ip4; +IP ip5; +IP ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \ +// expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}} +IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}} + +struct X { }; +template struct PM { // expected-note 2 {{template parameter is declared here}} + PM *pm2; +}; + +PM<0> pm0; // expected-error{{null non-type template argument must be cast to template parameter type 'int X::*'}} +PM<(0)> pm1; // expected-error{{null non-type template argument must be cast to template parameter type 'int X::*'}} +PM pm2; +PM pm3; +PM<(int X::*)0> pm4; +PM pm5; + +template struct PMF { // expected-note 2 {{template parameter is declared here}} + PMF *pmf2; +}; + +PMF<0> pmf0; // expected-error{{null non-type template argument must be cast to template parameter type 'int (X::*)(int)'}} +PMF<(0)> pmf1; // expected-error{{null non-type template argument must be cast to template parameter type 'int (X::*)(int)'}} +PMF pmf2; +PMF pmf3; +PMF<(int (X::*)(int))0> pmf4; +PMF pmf5; + + +template struct NP { // expected-note 2{{template parameter is declared here}} + NP *np2; +}; + +NP np1; +NP np2; +NP np3; +NP<0> np4; // expected-error{{null non-type template argument must be cast to template parameter type 'std::nullptr_t' (aka 'nullptr_t')}} +constexpr int i = 7; +NP np5; // expected-error{{non-type template argument of type 'const int' cannot be converted to a value of type 'std::nullptr_t'}} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp new file mode 100644 index 0000000..c4db002 --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu %s + +// C++11 [temp.arg.nontype]p1: +// +// A template-argument for a non-type, non-template template-parameter shall +// be one of: +// -- an integral constant expression; or +// -- the name of a non-type template-parameter ; or +namespace non_type_tmpl_param { + template struct X0 { X0(); }; + template X0::X0() { } + template struct X1 { X1(); }; + template X1::X1() { } + template struct X3 { X3(); }; + template X3::X3() { } + template struct X4 { X4(); }; + template X4::X4() { } + template struct X5 { X5(); }; + template X5::X5() { } +} + +// -- a constant expression that designates the address of an object with +// static storage duration and external or internal linkage or a function +// with external or internal linkage, including function templates and +// function template-ids, but excluting non-static class members, expressed +// (ignoring parentheses) as & id-expression, except that the & may be +// omitted if the name refers to a function or array and shall be omitted +// if the corresopnding template-parameter is a reference; or +namespace addr_of_obj_or_func { + template struct X0 { }; // expected-note 4{{here}} + template struct X1 { }; + template struct X2 { }; // expected-note 4{{here}} + template struct X2k { }; // expected-note {{here}} + template struct X3 { }; // expected-note 4{{here}} + + int i = 42; + int iarr[10]; + int f(int i); + const int ki = 9; // expected-note 5{{here}} + __thread int ti = 100; // expected-note 2{{here}} + static int f_internal(int); // expected-note 4{{here}} + template T f_tmpl(T t); + + void test() { + X0 x0a; // expected-error {{must have its address taken}} + X0<&i> x0a_addr; + X0 x0b; + X0<&iarr> x0b_addr; // expected-error {{cannot be converted to a value of type 'int *'}} + X0 x0c; // expected-error {{must have its address taken}} expected-warning {{internal linkage is a C++11 extension}} + X0<&ki> x0c_addr; // expected-error {{cannot be converted to a value of type 'int *'}} expected-warning {{internal linkage is a C++11 extension}} + X0<&ti> x0d_addr; // expected-error {{refers to thread-local object}} + X1 x1a; + X1<&f> x1a_addr; + X1 x1b; + X1<&f_tmpl> x1b_addr; + X1 > x1c; + X1<&f_tmpl > x1c_addr; + X1 x1d; // expected-warning {{internal linkage is a C++11 extension}} + X1<&f_internal> x1d_addr; // expected-warning {{internal linkage is a C++11 extension}} + X2 x2a; + X2<&i> x2a_addr; // expected-error {{address taken}} + X2 x2b; // expected-error {{cannot bind to template argument of type 'int [10]'}} + X2<&iarr> x2b_addr; // expected-error {{address taken}} + X2 x2c; // expected-error {{ignores qualifiers}} expected-warning {{internal linkage is a C++11 extension}} + X2k x2kc; // expected-warning {{internal linkage is a C++11 extension}} + X2k<&ki> x2kc_addr; // expected-error {{address taken}} expected-warning {{internal linkage is a C++11 extension}} + X2 x2d_addr; // expected-error {{refers to thread-local object}} + X3 x3a; + X3<&f> x3a_addr; // expected-error {{address taken}} + X3 x3b; + X3<&f_tmpl> x3b_addr; // expected-error {{address taken}} + X3 > x3c; + X3<&f_tmpl > x3c_addr; // expected-error {{address taken}} + X3 x3d; // expected-warning {{internal linkage is a C++11 extension}} + X3<&f_internal> x3d_addr; // expected-error {{address taken}} expected-warning {{internal linkage is a C++11 extension}} + + int n; // expected-note {{here}} + X0<&n> x0_no_linkage; // expected-error {{non-type template argument refers to object 'n' that does not have linkage}} + struct Local { static int f() {} }; // expected-note {{here}} + X1<&Local::f> x1_no_linkage; // expected-error {{non-type template argument refers to function 'f' that does not have linkage}} + } +} + +// -- a constant expression that evaluates to a null pointer value (4.10); or +// -- a constant expression that evaluates to a null member pointer value +// (4.11); or +// -- a pointer to member expressed as described in 5.3.1. + +namespace bad_args { + template struct X0 { }; // expected-note 2{{template parameter is declared here}} + int i = 42; + X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}} + int* iptr = &i; + X0 x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}} +} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp new file mode 100644 index 0000000..9b9b532 --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -0,0 +1,205 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [temp.arg.nontype] p5: +// The following conversions are performed on each expression used as +// a non-type template-argument. If a non-type template-argument cannot be +// converted to the type of the corresponding template-parameter then the +// program is ill-formed. +// -- for a non-type template-parameter of integral or enumeration type, +// integral promotions (4.5) and integral conversions (4.7) are applied. +namespace integral_parameters { + template struct X0 { }; + X0<17> x0i; + X0<'a'> x0c; + template struct X1 { }; + X1<100l> x1l; +} + +// -- for a non-type template-parameter of type pointer to object, +// qualification conversions (4.4) and the array-to-pointer conversion +// (4.2) are applied; if the template-argument is of type +// std::nullptr_t, the null pointer conversion (4.10) is applied. +namespace pointer_to_object_parameters { + // PR6226 + struct Str { + Str(const char *); + }; + + template + struct A { + Str get() { return s; } + }; + + char hello[6] = "Hello"; + extern const char world[6]; + const char world[6] = "world"; + void test() { + (void)A().get(); + (void)A().get(); + } + + class X { + public: + X(); + X(int, int); + operator int() const; + }; + + template struct A2; // expected-note{{template parameter is declared here}} + + X *X_ptr; + X an_X; + X array_of_Xs[10]; + A2 *a12; // expected-error{{must have its address taken}} + A2 *a13; + A2<&an_X> *a13_2; + A2<(&an_X)> *a13_3; // expected-warning{{address non-type template argument cannot be surrounded by parentheses}} + + // PR6244 + struct X1 {} X1v; + template struct X2 { }; + template struct X3 : X2 { }; + struct X4 : X3<&X1v> { }; + + // PR6563 + int *bar; + template struct zed {}; // expected-note 2{{template parameter is declared here}} + void g(zed*); // expected-error{{must have its address taken}} + + int baz; + void g2(zed*); // expected-error{{must have its address taken}} + + void g3(zed<&baz>*); // okay +} + +// -- For a non-type template-parameter of type reference to object, no +// conversions apply. The type referred to by the reference may be more +// cv-qualified than the (otherwise identical) type of the +// template-argument. The template-parameter is bound directly to the +// template-argument, which shall be an lvalue. +namespace reference_parameters { + template struct S0 { }; // expected-note 3 {{template parameter is declared here}} + template struct S1 { }; // expected-note 2 {{template parameter is declared here}} + template struct S2 { }; // expected-note 2 {{template parameter is declared here}} + template struct S3 { }; + int i; + extern const int ci; + volatile int vi; + extern const volatile int cvi; + void test() { + S0 s0; + S0 s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const int' ignores qualifiers}} + S0 s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'volatile int' ignores qualifiers}} + S0 s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const volatile int' ignores qualifiers}} + + S1 s1; + S1 s1c; + S1 s1v; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'volatile int' ignores qualifiers}} + S1 s1cv; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'const volatile int' ignores qualifiers}} + + S2 s2; + S2 s2c; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const int' ignores qualifiers}} + S2 s2v; + S2 s2cv; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const volatile int' ignores qualifiers}} + + S3 s3; + S3 s3c; + S3 s3v; + S3 s3cv; + } + + namespace PR6250 { + template void inc() { + ref++; // expected-error{{read-only variable is not assignable}} + } + + template void bind() { + T &ref2 = ref; // expected-error{{drops qualifiers}} + } + + int counter; + void test() { + inc(); // expected-note{{instantiation of}} + bind(); // expected-note{{instantiation of}} + } + } + + namespace PR6749 { + template struct foo {}; // expected-note{{template parameter is declared here}} + int x, &y = x; + foo f; // expected-error{{is not an object}} + } +} + +// -- For a non-type template-parameter of type pointer to function, the +// function-to-pointer conversion (4.3) is applied; if the +// template-argument is of type std::nullptr_t, the null pointer +// conversion (4.10) is applied. If the template-argument represents +// a set of overloaded functions (or a pointer to such), the matching +// function is selected from the set (13.4). +namespace pointer_to_function { + template struct X0 { }; // expected-note 3{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0); + void x0b(X0<&f>); + void x0c(X0); // expected-error{{non-type template argument of type 'int (float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0d(X0<&g>); // expected-error{{non-type template argument of type 'int (*)(float)' cannot be converted to a value of type 'int (*)(int)'}} + void x0e(X0); // expected-error{{must have its address taken}} +} + +// -- For a non-type template-parameter of type reference to function, no +// conversions apply. If the template-argument represents a set of +// overloaded functions, the matching function is selected from the set +// (13.4). +namespace reference_to_function { + template struct X0 { }; // expected-note 4{{template parameter is declared here}} + int f(int); + int f(float); + int g(float); + int (*funcptr)(int); + void x0a(X0); + void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0c(X0); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}} + void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} + void x0e(X0); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}} +} +// -- For a non-type template-parameter of type pointer to member function, +// if the template-argument is of type std::nullptr_t, the null member +// pointer conversion (4.11) is applied; otherwise, no conversions +// apply. If the template-argument represents a set of overloaded member +// functions, the matching member function is selected from the set +// (13.4). +namespace pointer_to_member_function { + struct X { }; + struct Y : X { + int f(int); + int g(int); + int g(float); + float h(float); + }; + + template struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::f> x0a; + X0<&Y::g> x0b; + X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}} +} + +// -- For a non-type template-parameter of type pointer to data member, +// qualification conversions (4.4) are applied; if the template-argument +// is of type std::nullptr_t, the null member pointer conversion (4.11) +// is applied. +namespace pointer_to_member_data { + struct X { int x; }; + struct Y : X { int y; }; + + template struct X0 {}; // expected-note{{template parameter is declared here}} + X0<&Y::y> x0a; + X0<&Y::x> x0b; // expected-error{{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}} + + // Test qualification conversions + template struct X1 {}; + X1<&Y::y> x1a; +} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp new file mode 100644 index 0000000..1c13bff --- /dev/null +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template struct eval; // expected-note 3{{template is declared here}} + +template