diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
index a124bff84c7..245826b1a14 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -29,7 +29,7 @@ import java.lang.annotation.Annotation;
 import java.lang.annotation.Inherited;
 import java.util.Collections;
 import java.util.EnumSet;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
@@ -1780,6 +1780,8 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
         /* the original annotations applied to the record component
          */
         private final List<JCAnnotation> originalAnnos;
+
+        private Set<JCAnnotation> propagatedAnnos = new HashSet<>();
         /* if the user happens to erroneously declare two components with the same name, we need a way to differentiate
          * them, the code will fail anyway but we need to keep the information for better error recovery
          */
@@ -1824,6 +1826,34 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
             return v.visitRecordComponent(this, p);
         }
+
+        public void setProcessedAnnos(List<? extends Attribute.Compound> processedAnnos) {
+            if (processedAnnos != null && !processedAnnos.isEmpty()) {
+                for (Attribute.Compound compound : processedAnnos) {
+                    for (JCAnnotation annoTree : originalAnnos) {
+                        annoTree.attribute = compound;
+                        annoTree.type = compound.type;
+                    }
+                }
+            }
+        }
+
+        public void setAsPropagated(JCAnnotation originalAnno) {
+            propagatedAnnos.add(originalAnno);
+        }
+
+        public void setAsPropagated(Attribute.Compound compound) {
+            for (JCAnnotation anno : originalAnnos) {
+                if (compound.type.tsym == compound.type.tsym) {
+                    propagatedAnnos.add(anno);
+                    return;
+                }
+            }
+        }
+
+        public boolean isPropagated(JCAnnotation originalAnno) {
+            return propagatedAnnos.contains(originalAnno);
+        }
     }
 
     public static class ParamSymbol extends VarSymbol {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
index 0041b402449..117b521e28d 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -1045,28 +1045,44 @@ public class Attr extends JCTree.Visitor {
 
             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP) {
                 // lets find if this method is an accessor
-                Optional<? extends RecordComponent> recordComponent = env.enclClass.sym.getRecordComponents().stream()
-                        .filter(rc -> rc.accessor == tree.sym && (rc.accessor.flags_field & GENERATED_MEMBER) == 0).findFirst();
-                if (recordComponent.isPresent()) {
-                    // the method is a user defined accessor lets check that everything is fine
-                    if (!tree.sym.isPublic()) {
-                        log.error(tree, Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.MethodMustBePublic));
-                    }
-                    if (!types.isSameType(tree.sym.type.getReturnType(), recordComponent.get().type)) {
-                        log.error(tree, Errors.InvalidAccessorMethodInRecord(env.enclClass.sym,
-                                Fragments.AccessorReturnTypeDoesntMatch(tree.sym, recordComponent.get())));
-                    }
-                    if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
-                        log.error(tree,
-                                Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodCantThrowException));
-                    }
-                    if (!tree.typarams.isEmpty()) {
-                        log.error(tree,
-                                Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodMustNotBeGeneric));
+                Optional<? extends RecordComponent> recordComponentOp = env.enclClass.sym.getRecordComponents().stream()
+                        .filter(rc -> rc.accessor == tree.sym).findFirst();
+                if (recordComponentOp.isPresent()) {
+                    RecordComponent rc = recordComponentOp.get();
+                    boolean userDefined = (rc.accessor.flags_field & GENERATED_MEMBER) == 0;
+                    if (userDefined) {
+                        // the method is a user defined accessor lets check that everything is fine
+                        if (!tree.sym.isPublic()) {
+                            log.error(tree, Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.MethodMustBePublic));
+                        }
+                        if (!types.isSameType(tree.sym.type.getReturnType(), rc.type)) {
+                            log.error(tree, Errors.InvalidAccessorMethodInRecord(env.enclClass.sym,
+                                    Fragments.AccessorReturnTypeDoesntMatch(tree.sym, rc)));
+                        }
+                        if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
+                            log.error(tree,
+                                    Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodCantThrowException));
+                        }
+                        if (!tree.typarams.isEmpty()) {
+                            log.error(tree,
+                                    Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodMustNotBeGeneric));
+                        }
+                        if (tree.sym.isStatic()) {
+                            log.error(tree,
+                                    Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodMustNotBeStatic));
+                        }
                     }
-                    if (tree.sym.isStatic()) {
-                        log.error(tree,
-                                Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodMustNotBeStatic));
+                    // now let's mark the original annotation as propagated if applicable
+                    List<JCAnnotation> originalAnnos = rc.getOriginalAnnos();
+                    if (!userDefined) {
+                        /* the accessor has been generated by the compiler, lets mark the corresponding annotation
+                         * in the record component (if applicable) as propagated
+                         */
+                        /*for (JCAnnotation anno : originalAnnos) {
+                            if (Arrays.stream(chk.getTargetNames(anno.type.tsym)).anyMatch(name -> name == names.METHOD)) {
+                                rc.setAsPropagated(anno);
+                            }
+                        }*/
                     }
                 }
 
@@ -1086,7 +1102,8 @@ public class Attr extends JCTree.Visitor {
                          *     - have an accessibility stricter than that of the record type
                          *     - explicitly invoke any other constructor
                          */
-                        if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
+                        boolean userGenerated = (tree.sym.flags_field & GENERATEDCONSTR) == 0;
+                        if (userGenerated) {
                             if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
                                 log.error(tree,
                                         (env.enclClass.sym.flags() & AccessFlags) == 0 ?
@@ -1120,18 +1137,29 @@ public class Attr extends JCTree.Visitor {
                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
                         }
 
-                        /* and now we need to check that the constructor's arguments are exactly the same as those of the
-                         * record components
+                        /* and now for user generated canonical constructors, we need to check that the constructor's
+                         * arguments are exactly the same as those of the record components and for compiler generated
+                         * canonical constructors we need to mark as propagated any annotation coming from the
+                         * corresponding record component
                          */
                         List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
                         List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
                         for (JCVariableDecl param: tree.params) {
-                            boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
-                            if (!types.isSameType(param.type, recordFieldTypes.head) ||
-                                    (recordComponents.head.isVarargs() != paramIsVarArgs)) {
-                                log.error(param, Errors.InvalidCanonicalConstructorInRecord(
-                                        Fragments.Canonical, env.enclClass.sym.name,
-                                        Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
+                            if (userGenerated) {
+                                boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
+                                if (!types.isSameType(param.type, recordFieldTypes.head) ||
+                                        (recordComponents.head.isVarargs() != paramIsVarArgs)) {
+                                    log.error(param, Errors.InvalidCanonicalConstructorInRecord(
+                                            Fragments.Canonical, env.enclClass.sym.name,
+                                            Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
+                                }
+                            } else {
+                                /*List<JCAnnotation> originalAnnos = recordComponents.head.getOriginalAnnos();
+                                for (JCAnnotation anno : originalAnnos) {
+                                    if (Arrays.stream(chk.getTargetNames(anno.type.tsym)).anyMatch(name -> name == names.PARAMETER)) {
+                                        recordComponents.head.setAsPropagated(anno);
+                                    }
+                                }*/
                             }
                             recordComponents = recordComponents.tail;
                             recordFieldTypes = recordFieldTypes.tail;
@@ -5203,6 +5231,26 @@ public class Attr extends JCTree.Visitor {
                 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
                 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
                 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
+                if (c.isRecord()) {
+                    /* now we have to check that all the annotations originally applied to the record components
+                     * have been propagated to the members, automatic propagation could be affected if the user
+                     * defines a record member manually, especifically accessors and or canonical constructor.
+                     * For annotations with targets FIELD, RECORD_COMPONENT and TYPE_USE we don't have to worry as the
+                     * compiler will always be able to propagate them. So we care about annotations that only have
+                     * targets: (METHOD | PARAMETER)
+                     */
+                    List<? extends RecordComponent> recordComponents = c.getRecordComponents();
+                    for (RecordComponent rc : recordComponents) {
+                        List<JCAnnotation> originalAnnos = rc.getOriginalAnnos();
+                        for (JCAnnotation origAnno : originalAnnos) {
+                            if (!rc.isPropagated(origAnno) &&
+                                !Arrays.stream(chk.getTargetNames(origAnno.type.tsym))
+                                        .anyMatch(name -> name == names.FIELD || name == names.RECORD_COMPONENT || name == names.TYPE_USE)) {
+                                log.error(origAnno, Errors.AnnotationNotPropagated(origAnno.attribute.type));
+                            }
+                        }
+                    }
+                }
             } finally {
                 env.info.returnResult = prevReturnRes;
                 log.useSource(prev);
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
index baff49db6d7..a406eb51f94 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
@@ -2947,6 +2947,9 @@ public class Check {
                     rc.setTypeAttributes(s.getRawTypeAttributes());
                     // to get all the type annotations applied to the type
                     rc.type = s.type;
+                    // we are storing the annotations once processed by the compiler in the record component
+                    rc.setProcessedAnnos(s.getRawAttributes());
+                    //rc.setProcessedAnnos(s.getRawTypeAttributes());
                 }
             }
         }
@@ -3003,8 +3006,9 @@ public class Check {
                 Set<Name> applicableTargets = applicableTargetsOp.get();
                 boolean notApplicableOrIsTypeUseOnly = applicableTargets.isEmpty() ||
                         applicableTargets.size() == 1 && applicableTargets.contains(names.TYPE_USE);
+                boolean isGeneratedRecordElement = (s.flags_field & Flags.GENERATED_MEMBER) != 0;
                 boolean isRecordMemberWithNonApplicableDeclAnno =
-                        isRecordMember && (s.flags_field & Flags.GENERATED_MEMBER) != 0 && notApplicableOrIsTypeUseOnly;
+                        isRecordMember && isGeneratedRecordElement && notApplicableOrIsTypeUseOnly;
 
                 if (applicableTargets.isEmpty() || isRecordMemberWithNonApplicableDeclAnno) {
                     if (isRecordMemberWithNonApplicableDeclAnno) {
@@ -3031,6 +3035,14 @@ public class Check {
                         log.error(a.pos(), Errors.AnnotationTypeNotApplicable);
                     }
                 }
+                if (isRecordMember && isGeneratedRecordElement && !isRecordField) {
+                    // generated canonical or generated accessor
+                    RecordComponent rc = s.enclClass().getRecordComponents().stream().filter(rcomp -> rcomp.name == s.name).findFirst().get();
+                    Assert.checkNonNull(rc, "internal assertion error: cannot find record component named " + s.name);
+                    for (Attribute.Compound compAttr : s.getRawAttributes()) {
+                        rc.setAsPropagated(compAttr);
+                    }
+                }
             }
         }
 
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
index bc8d3008679..588ecb88ac2 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -3611,6 +3611,10 @@ compiler.err.static.declaration.not.allowed.in.inner.classes=\
 compiler.err.record.header.expected=\
     record header expected
 
+# 0: type
+compiler.err.annotation.not.propagated=\
+    annotation @{0} is not propagated to any record element
+
 ############################################
 # messages previously at javac.properties
 
diff --git a/test/langtools/tools/javac/diags/examples/AnnotationsNotPropagated.java b/test/langtools/tools/javac/diags/examples/AnnotationsNotPropagated.java
new file mode 100644
index 00000000000..136d1d0f567
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/AnnotationsNotPropagated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.annotation.not.propagated
+// key: compiler.note.preview.filename
+// key: compiler.note.preview.recompile
+// options: --enable-preview -source ${jdk.version}
+
+import java.lang.annotation.*;
+
+@Target({ElementType.PARAMETER})
+@interface A {}
+
+record R(@A String s) {
+    R(String s) {
+        this.s = s;
+    }
+}
diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java
index bc3be98c72d..a37e8f4799f 100644
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java
+++ b/test/langtools/tools/javac/records/RecordCompilationTests.java
@@ -1707,4 +1707,65 @@ public class RecordCompilationTests extends CompilationTestCase {
                 """
         );
     }
+
+    public void testAnnosNotBeingPropagated() {
+        assertFail("compiler.err.annotation.not.propagated",
+                """
+                import java.lang.annotation.*;
+                @Target({ElementType.PARAMETER})
+                @interface A{ String value(); }
+
+                record R(@A("A") String s) {
+                    R(String s) {
+                        this.s = s;
+                    }
+                }
+                """
+        );
+        /*
+        assertFail("compiler.err.annotation.not.propagated",
+                """
+                import java.lang.annotation.*;
+
+                //@Target(ElementType.METHOD)
+                @Target({ElementType.PARAMETER})
+                //@Target({ElementType.METHOD, ElementType.PARAMETER})
+                @interface DevAnnotation{ String value(); }
+
+                record R(@DevAnnotation("devA") String s) {     // Error!
+
+                    R(String s) {
+                        this.s = s;
+                    }
+
+
+                    //public String s() { return s; }
+                    //public @DevAnnotation("devA") String s() { return s; }
+                }
+
+                """
+        );
+        assertFail("compiler.err.annotation.not.propagated",
+                """
+                import java.lang.annotation.*;
+
+                //@Target(ElementType.METHOD)
+                @Target({ElementType.PARAMETER})
+                //@Target({ElementType.METHOD, ElementType.PARAMETER})
+                @interface DevAnnotation{ String value(); }
+
+                record R(@DevAnnotation("devA") String s) {     // Error!
+
+                    R(String s) {
+                        this.s = s;
+                    }
+
+
+                    //public String s() { return s; }
+                    //public @DevAnnotation("devA") String s() { return s; }
+                }
+                """
+        );
+        */
+    }
 }
